Depth fixup
This commit is contained in:
Родитель
0732c09e39
Коммит
dea1148ccb
|
@ -7,7 +7,7 @@ namespace BoyarPeralta11
|
|||
open Microsoft.Quantum.Intrinsic;
|
||||
open QUtilities;
|
||||
|
||||
operation ForwardSBox(u: Qubit[], s: Qubit[], t: Qubit[], m: Qubit[], l: Qubit[], costing: Bool) : Unit
|
||||
operation ForwardSBox(u: Qubit[], s: Qubit[], t: Qubit[], m: Qubit[], l: Qubit[], anc: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
|
@ -39,69 +39,75 @@ namespace BoyarPeralta11
|
|||
LPXOR(t[3-1], t[16-1], t[26-1]);
|
||||
LPXOR(t[1-1], t[12-1], t[27-1]);
|
||||
|
||||
LPAND(t[13-1], t[6-1], m[1-1], costing);
|
||||
LPAND(t[23-1], t[8-1], m[2-1], costing);
|
||||
LPXOR(t[14-1], m[1-1], m[3-1]);
|
||||
LPAND(t[19-1], u[7], m[4-1], costing);
|
||||
LPXOR(m[4-1], m[1-1], m[5-1]);
|
||||
LPAND(t[3-1], t[16-1], m[6-1], costing);
|
||||
LPAND(t[22-1], t[9-1], m[7-1], costing);
|
||||
LPXOR(t[26-1], m[6-1], m[8-1]);
|
||||
LPAND(t[20-1], t[17-1], m[9-1], costing);
|
||||
LPXOR(m[9-1], m[6-1], m[10-1]);
|
||||
LPAND(t[1-1], t[15-1], m[11-1], costing);
|
||||
LPAND(t[4-1], t[27-1], m[12-1], costing);
|
||||
LPXOR(m[12-1], m[11-1], m[13-1]);
|
||||
LPAND(t[2-1], t[10-1], m[14-1], costing);
|
||||
LPXOR(m[14-1], m[11-1], m[15-1]);
|
||||
LPXOR(m[3-1], m[2-1], m[16-1]);
|
||||
LPXOR(m[5-1], t[24-1], m[17-1]);
|
||||
LPXOR(m[8-1], m[7-1], m[18-1]);
|
||||
LPXOR(m[10-1], m[15-1], m[19-1]);
|
||||
LPXOR(m[16-1], m[13-1], m[20-1]);
|
||||
LPXOR(m[17-1], m[15-1], m[21-1]);
|
||||
LPXOR(m[18-1], m[13-1], m[22-1]);
|
||||
LPXOR(m[19-1], t[25-1], m[23-1]);
|
||||
LPXOR(m[22-1], m[23-1], m[24-1]);
|
||||
LPAND(m[22-1], m[20-1], m[25-1], costing);
|
||||
LPXOR(m[21-1], m[25-1], m[26-1]);
|
||||
LPXOR(m[20-1], m[21-1], m[27-1]);
|
||||
LPXOR(m[23-1], m[25-1], m[28-1]);
|
||||
LPAND(m[28-1], m[27-1], m[29-1], costing);
|
||||
LPAND(m[26-1], m[24-1], m[30-1], costing);
|
||||
LPAND(m[20-1], m[23-1], m[31-1], costing);
|
||||
LPAND(m[27-1], m[31-1], m[32-1], costing);
|
||||
LPXOR(m[27-1], m[25-1], m[33-1]);
|
||||
LPAND(m[21-1], m[22-1], m[34-1], costing);
|
||||
LPAND(m[24-1], m[34-1], m[35-1], costing);
|
||||
LPXOR(m[24-1], m[25-1], m[36-1]);
|
||||
LPXOR(m[21-1], m[29-1], m[37-1]);
|
||||
LPXOR(m[32-1], m[33-1], m[38-1]);
|
||||
LPXOR(m[23-1], m[30-1], m[39-1]);
|
||||
LPXOR(m[35-1], m[36-1], m[40-1]);
|
||||
LPXOR(m[38-1], m[40-1], m[41-1]);
|
||||
LPXOR(m[37-1], m[39-1], m[42-1]);
|
||||
LPXOR(m[37-1], m[38-1], m[43-1]);
|
||||
LPXOR(m[39-1], m[40-1], m[44-1]);
|
||||
LPXOR(m[42-1], m[41-1], m[45-1]);
|
||||
LPAND(m[44-1], t[6-1], m[46-1], costing);
|
||||
LPAND(m[40-1], t[8-1], m[47-1], costing);
|
||||
LPAND(m[39-1], u[7], m[48-1], costing);
|
||||
LPAND(m[43-1], t[16-1], m[49-1], costing);
|
||||
LPAND(m[38-1], t[9-1], m[50-1], costing);
|
||||
LPAND(m[37-1], t[17-1], m[51-1], costing);
|
||||
LPAND(m[42-1], t[15-1], m[52-1], costing);
|
||||
LPAND(m[45-1], t[27-1], m[53-1], costing);
|
||||
LPAND(m[41-1], t[10-1], m[54-1], costing);
|
||||
LPAND(m[44-1], t[13-1], m[55-1], costing);
|
||||
LPAND(m[40-1], t[23-1], m[56-1], costing);
|
||||
LPAND(m[39-1], t[19-1], m[57-1], costing);
|
||||
LPAND(m[43-1], t[3-1], m[58-1], costing);
|
||||
LPAND(m[38-1], t[22-1], m[59-1], costing);
|
||||
LPAND(m[37-1], t[20-1], m[60-1], costing);
|
||||
LPAND(m[42-1], t[1-1], m[61-1], costing);
|
||||
LPAND(m[45-1], t[4-1], m[62-1], costing);
|
||||
LPAND(m[41-1], t[2-1], m[63-1], costing);
|
||||
|
||||
LPANDWithAux(t[13-1], t[6-1], m[1-1], anc[0], costing); // depth 0->1
|
||||
LPANDWithAux(t[23-1], t[8-1], m[2-1], anc[1], costing); // depth 0->1
|
||||
LPANDWithAux(t[19-1], u[7], m[4-1], anc[2], costing); // depth 0->1
|
||||
LPANDWithAux(t[3-1], t[16-1], m[6-1], anc[3], costing); // depth 0->1
|
||||
LPANDWithAux(t[22-1], t[9-1], m[7-1], anc[4], costing); // depth 0->1
|
||||
LPANDWithAux(t[20-1], t[17-1], m[9-1], anc[5], costing); // depth 0->1
|
||||
LPANDWithAux(t[1-1], t[15-1], m[11-1], anc[6], costing); // depth 0->1
|
||||
LPANDWithAux(t[4-1], t[27-1], m[12-1], anc[7], costing); // depth 0->1
|
||||
LPANDWithAux(t[2-1], t[10-1], m[14-1], anc[8], costing); // depth 0->1
|
||||
|
||||
LPXOR(t[14-1], m[1-1], m[3-1]); // depth 1->1
|
||||
LPXOR(m[4-1], m[1-1], m[5-1]); // depth 1->1
|
||||
LPXOR(t[26-1], m[6-1], m[8-1]); // depth 1->1
|
||||
LPXOR(m[9-1], m[6-1], m[10-1]); // depth 1->1
|
||||
LPXOR(m[12-1], m[11-1], m[13-1]); // depth 1->1
|
||||
LPXOR(m[14-1], m[11-1], m[15-1]); // depth 1->1
|
||||
LPXOR(m[3-1], m[2-1], m[16-1]); // depth 1->1
|
||||
LPXOR(m[5-1], t[24-1], m[17-1]); // depth 1->1
|
||||
LPXOR(m[8-1], m[7-1], m[18-1]); // depth 1->1
|
||||
LPXOR(m[10-1], m[15-1], m[19-1]); // depth 1->1
|
||||
LPXOR(m[16-1], m[13-1], m[20-1]); // depth 1->1
|
||||
LPXOR(m[17-1], m[15-1], m[21-1]); // depth 1->1
|
||||
LPXOR(m[18-1], m[13-1], m[22-1]); // depth 1->1
|
||||
LPXOR(m[19-1], t[25-1], m[23-1]); // depth 1->1
|
||||
LPXOR(m[22-1], m[23-1], m[24-1]); // depth 1->1
|
||||
LPANDWithAux(m[22-1], m[20-1], m[25-1], anc[0], costing); // depth 1->2
|
||||
|
||||
LPXOR(m[21-1], m[25-1], m[26-1]); // depth 2->2
|
||||
LPXOR(m[20-1], m[21-1], m[27-1]); // depth 2->2
|
||||
LPXOR(m[23-1], m[25-1], m[28-1]); // depth 2->2
|
||||
LPANDWithAux(m[28-1], m[27-1], m[29-1], anc[0], costing); // depth 2->3
|
||||
LPANDWithAux(m[26-1], m[24-1], m[30-1], anc[1], costing); // depth 2->3
|
||||
LPANDWithAux(m[20-1], m[23-1], m[31-1], anc[2], costing); // depth 2->3
|
||||
LPANDWithAux(m[21-1], m[22-1], m[34-1], anc[3], costing); // depth 2->3
|
||||
|
||||
LPANDWithAux(m[27-1], m[31-1], m[32-1], anc[0], costing); // depth 3->4
|
||||
LPANDWithAux(m[24-1], m[34-1], m[35-1], anc[1], costing); // depth 3->4
|
||||
LPXOR(m[21-1], m[29-1], m[37-1]); // depth 3->3
|
||||
LPXOR(m[23-1], m[30-1], m[39-1]); // depth 3->3
|
||||
LPXOR(m[37-1], m[39-1], m[42-1]); // depth 3->3
|
||||
|
||||
LPXOR(m[27-1], m[25-1], m[33-1]); // depth 4->4
|
||||
LPXOR(m[24-1], m[25-1], m[36-1]); // depth 4->4
|
||||
LPXOR(m[32-1], m[33-1], m[38-1]); // depth 4->4
|
||||
LPXOR(m[35-1], m[36-1], m[40-1]); // depth 4->4
|
||||
LPXOR(m[38-1], m[40-1], m[41-1]); // depth 4->4
|
||||
LPXOR(m[37-1], m[38-1], m[43-1]); // depth 4->4
|
||||
LPXOR(m[39-1], m[40-1], m[44-1]); // depth 4->4
|
||||
LPXOR(m[42-1], m[41-1], m[45-1]); // depth 4->4
|
||||
LPANDWithAux(m[44-1], t[6-1], m[46-1], anc[0], costing); // depth 4->5
|
||||
LPANDWithAux(m[40-1], t[8-1], m[47-1], anc[1], costing); // depth 4->5
|
||||
LPANDWithAux(m[39-1], u[7], m[48-1], anc[2], costing); // depth 4->5
|
||||
LPANDWithAux(m[43-1], t[16-1], m[49-1], anc[3], costing); // depth 4->5
|
||||
LPANDWithAux(m[38-1], t[9-1], m[50-1], anc[4], costing); // depth 4->5
|
||||
LPANDWithAux(m[37-1], t[17-1], m[51-1], anc[5], costing); // depth 4->5
|
||||
LPANDWithAux(m[42-1], t[15-1], m[52-1], anc[6], costing); // depth 4->5
|
||||
LPANDWithAux(m[45-1], t[27-1], m[53-1], anc[7], costing); // depth 4->5
|
||||
LPANDWithAux(m[41-1], t[10-1], m[54-1], anc[8], costing); // depth 4->5
|
||||
|
||||
LPANDWithAux(m[44-1], t[13-1], m[55-1], anc[0], costing); // depth 5->6
|
||||
LPANDWithAux(m[40-1], t[23-1], m[56-1], anc[1], costing); // depth 5->6
|
||||
LPANDWithAux(m[39-1], t[19-1], m[57-1], anc[2], costing); // depth 5->6
|
||||
LPANDWithAux(m[43-1], t[3-1], m[58-1], anc[3], costing); // depth 5->6
|
||||
LPANDWithAux(m[38-1], t[22-1], m[59-1], anc[4], costing); // depth 5->6
|
||||
LPANDWithAux(m[37-1], t[20-1], m[60-1], anc[5], costing); // depth 5->6
|
||||
LPANDWithAux(m[42-1], t[1-1], m[61-1], anc[6], costing); // depth 5->6
|
||||
LPANDWithAux(m[45-1], t[4-1], m[62-1], anc[7], costing); // depth 5->6
|
||||
LPANDWithAux(m[41-1], t[2-1], m[63-1], anc[8], costing); // depth 5->6
|
||||
|
||||
LPXOR(m[61-1], m[62-1], l[0]);
|
||||
LPXOR(m[50-1], m[56-1], l[1]);
|
||||
|
@ -182,34 +188,57 @@ namespace BoyarPeralta11
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation SBox (input: Qubit[], output: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
use (t, m, l) = (Qubit[27], Qubit[63], Qubit[30])
|
||||
{
|
||||
let u = input[7..(-1)..0];
|
||||
let s = output[7..(-1)..0];
|
||||
function SBoxAncCount() : Int {
|
||||
return 129;
|
||||
}
|
||||
|
||||
ForwardSBox(u, s, t, m, l, costing);
|
||||
|
||||
// get out result
|
||||
LPXOR(l[6], l[24], s[0]);
|
||||
LPXNOR(l[16], l[26], s[1]);
|
||||
LPXNOR(l[19], l[28], s[2]);
|
||||
LPXOR(l[6], l[21], s[3]);
|
||||
LPXOR(l[20], l[22], s[4]);
|
||||
LPXOR(l[25], l[29], s[5]);
|
||||
LPXNOR(l[13], l[27], s[6]);
|
||||
LPXNOR(l[6], l[23], s[7]);
|
||||
|
||||
// uncompute
|
||||
(Adjoint ForwardSBox)(u, s, t, m, l, costing);
|
||||
|
||||
// // dummy, forced-T-depth 2 s-box
|
||||
// DummySBox(input, output, 2);
|
||||
operation SBox (input: Qubit[], output: Qubit[], ancAll: Qubit[], costing: Bool) : Unit {
|
||||
body (...){
|
||||
if Length(ancAll) < 129 {
|
||||
let nExtra = 129 - Length(ancAll);
|
||||
use extraAnc = Qubit[nExtra] {
|
||||
_SBox(input, output, ancAll + extraAnc, costing);
|
||||
}
|
||||
} else {
|
||||
_SBox(input, output, ancAll, costing);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation _SBox (input: Qubit[], output: Qubit[], ancAll: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
// Bookkeeping
|
||||
let anc = Microsoft.Quantum.Arrays.Partitioned([27,63,30,9], ancAll);
|
||||
let t = anc[0];
|
||||
let m = anc[1];
|
||||
let l = anc[2];
|
||||
let ancAnd = anc[3];
|
||||
let u = input[7..(-1)..0];
|
||||
let s = output[7..(-1)..0];
|
||||
|
||||
ForwardSBox(u, s, t, m, l, ancAnd, costing);
|
||||
|
||||
// get out result
|
||||
LPXOR(l[6], l[24], s[0]);
|
||||
LPXNOR(l[16], l[26], s[1]);
|
||||
LPXNOR(l[19], l[28], s[2]);
|
||||
LPXOR(l[6], l[21], s[3]);
|
||||
LPXOR(l[20], l[22], s[4]);
|
||||
LPXOR(l[25], l[29], s[5]);
|
||||
LPXNOR(l[13], l[27], s[6]);
|
||||
LPXNOR(l[6], l[23], s[7]);
|
||||
|
||||
// uncompute
|
||||
(Adjoint ForwardSBox)(u, s, t, m, l, ancAnd, costing);
|
||||
|
||||
// // dummy, forced-T-depth 2 s-box
|
||||
// DummySBox(input, output, 2);
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace cswrapper
|
|||
|
||||
Console.Write("operation, CNOT count, 1-qubit Clifford count, T count, R count, M count, T depth, initial width, extra width, comment, full depth");
|
||||
|
||||
Estimates.DepthTest<QTests.GF256.MeasureDepth>();
|
||||
Estimates.AllOnesTest<QTests.GF256.TestAllOnes>();
|
||||
|
||||
// GF256
|
||||
Estimates.Mul<QGF256.Mul>("unrolled = false", false, free_swaps);
|
||||
Estimates.Mul<QGF256.UnrolledMul>("unrolled = true", true, free_swaps);
|
||||
|
@ -131,26 +134,29 @@ namespace cswrapper
|
|||
Estimates.Rijndael<QAES.Widest.Rijndael>("smart_wide = false - Nr = 12 - Nk = 6", false, 12, 6, true, free_swaps, "_192_in-place-MC");
|
||||
Estimates.Rijndael<QAES.Widest.Rijndael>("smart_wide = false - Nr = 14 - Nk = 8", false, 14, 8, true, free_swaps, "_256_in-place-MC");
|
||||
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 1", true, 1, 10, 4, true, free_swaps, "_128_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 1", true, 1, 12, 6, true, free_swaps, "_192_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 1", true, 1, 14, 8, true, free_swaps, "_256_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 2", true, 2, 10, 4, true, free_swaps, "_128_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 2", true, 2, 12, 6, true, free_swaps, "_192_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 2", true, 2, 14, 8, true, free_swaps, "_256_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 3", true, 3, 10, 4, true, free_swaps, "_128_in-place-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 3", true, 3, 12, 6, true, free_swaps, "_192_in-place-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 3", true, 3, 14, 8, true, free_swaps, "_256_in-place-MC_r3");
|
||||
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 1", true, 1, 10, 4, false, free_swaps, "_128_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 1", true, 1, 12, 6, false, free_swaps, "_192_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 1", true, 1, 14, 8, false, free_swaps, "_256_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 2", true, 2, 10, 4, false, free_swaps, "_128_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 2", true, 2, 12, 6, false, free_swaps, "_192_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 2", true, 2, 14, 8, false, free_swaps, "_256_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 3", true, 3, 10, 4, false, free_swaps, "_128_maximov-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 3", true, 3, 12, 6, false, free_swaps, "_192_maximov-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>("smart_wide = true - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 3", true, 3, 14, 8, false, free_swaps, "_256_maximov-MC_r3");
|
||||
bool widest = false;
|
||||
for (int i=0; i < 2; i++){
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 1", widest, 1, 10, 4, true, free_swaps, "_128_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 1", widest, 1, 12, 6, true, free_swaps, "_192_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 1", widest, 1, 14, 8, true, free_swaps, "_256_in-place-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 2", widest, 2, 10, 4, true, free_swaps, "_128_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 2", widest, 2, 12, 6, true, free_swaps, "_192_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 2", widest, 2, 14, 8, true, free_swaps, "_256_in-place-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - in_place mixcolumn - r = 3", widest, 3, 10, 4, true, free_swaps, "_128_in-place-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - in_place mixcolumn - r = 3", widest, 3, 12, 6, true, free_swaps, "_192_in-place-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - in_place mixcolumn - r = 3", widest, 3, 14, 8, true, free_swaps, "_256_in-place-MC_r3");
|
||||
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 1", widest, 1, 10, 4, false, free_swaps, "_128_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 1", widest, 1, 12, 6, false, free_swaps, "_192_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 1", widest, 1, 14, 8, false, free_swaps, "_256_maximov-MC_r1");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 2", widest, 2, 10, 4, false, free_swaps, "_128_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 2", widest, 2, 12, 6, false, free_swaps, "_192_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 2", widest, 2, 14, 8, false, free_swaps, "_256_maximov-MC_r2");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 10 - Nk = 4 - Maximov's mixcolumn - r = 3", widest, 3, 10, 4, false, free_swaps, "_128_maximov-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 12 - Nk = 6 - Maximov's mixcolumn - r = 3", widest, 3, 12, 6, false, free_swaps, "_192_maximov-MC_r3");
|
||||
Estimates.GroverOracle<QAES.SmartWide.GroverOracle>($"widest = {widest} - Nr = 14 - Nk = 8 - Maximov's mixcolumn - r = 3", widest, 3, 14, 8, false, free_swaps, "_256_maximov-MC_r3");
|
||||
widest = true;
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT license.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Quantum.Simulation.Simulators;
|
||||
using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;
|
||||
using Microsoft.Quantum.Simulation.Core;
|
||||
using static Utilities;
|
||||
|
@ -18,16 +19,19 @@ namespace cswrapper
|
|||
config.UseWidthCounter = true;
|
||||
config.UsePrimitiveOperationsCounter = true;
|
||||
config.ThrowOnUnconstrainedMeasurement = false;
|
||||
config.OptimizeDepth = true;
|
||||
config.OptimizeDepth = false;
|
||||
if (full_depth)
|
||||
{
|
||||
config.TraceGateTimes[PrimitiveOperationsGroups.CNOT] = 1;
|
||||
config.TraceGateTimes[PrimitiveOperationsGroups.Measure] = 1; // count all one and 2 qubit measurements as depth 1
|
||||
config.TraceGateTimes[PrimitiveOperationsGroups.QubitClifford] = 1; // qubit Clifford depth 1
|
||||
}
|
||||
return new QCTraceSimulator(config);
|
||||
return new ResourcesEstimator(config);
|
||||
// return new QCTraceSimulator(config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void ProcessSim<Qop>(QCTraceSimulator sim, string comment = "", bool full_depth = false, string suffix="")
|
||||
{
|
||||
if (!full_depth)
|
||||
|
@ -52,6 +56,25 @@ namespace cswrapper
|
|||
}
|
||||
}
|
||||
|
||||
public static void DepthTest<Qop>()
|
||||
{
|
||||
var sim = getTraceSimulator(false);
|
||||
var res = QTests.GF256.MeasureDepth.Run(sim).Result;
|
||||
ProcessSim<Qop>(sim, "");
|
||||
sim = getTraceSimulator(true);
|
||||
res = QTests.GF256.MeasureDepth.Run(sim).Result;
|
||||
ProcessSim<Qop>(sim, "", true);
|
||||
}
|
||||
public static void AllOnesTest<Qop>()
|
||||
{
|
||||
var sim = getTraceSimulator(false);
|
||||
var res = QTests.GF256.TestAllOnes.Run(sim, 128, true).Result;
|
||||
ProcessSim<Qop>(sim, "");
|
||||
sim = getTraceSimulator(true);
|
||||
res = QTests.GF256.TestAllOnes.Run(sim, 128, true).Result;
|
||||
ProcessSim<Qop>(sim, "", true);
|
||||
}
|
||||
|
||||
public static void Mul<Qop>(string comment = "", bool unrolled = false, bool free_swaps = true)
|
||||
{
|
||||
var sim = getTraceSimulator(false);
|
||||
|
@ -250,27 +273,23 @@ namespace cswrapper
|
|||
ProcessSim<Qop>(sim, comment, true);
|
||||
}
|
||||
|
||||
public static void GroverOracle<Qop>(string comment = "", bool smart_wide = true, int pairs = 1, int Nr = 10, int Nk = 4, bool in_place_mixcolumn = true, bool free_swaps = true, string suffix = "")
|
||||
public static void GroverOracle<Qop>(string comment = "", bool widest = false, int pairs = 1, int Nr = 10, int Nk = 4, bool in_place_mixcolumn = true, bool free_swaps = true, string suffix = "")
|
||||
{
|
||||
var sim = getTraceSimulator(false);
|
||||
if (smart_wide)
|
||||
{
|
||||
var res = QTests.AES.SmartWideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128*pairs, false), nBits(128*pairs, false), pairs, Nr, Nk, in_place_mixcolumn, free_swaps).Result;
|
||||
}
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
var res = QTests.AES.SmartWideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128*pairs, false), nBits(128*pairs, false), pairs, Nr, Nk, in_place_mixcolumn, widest, free_swaps).Result;
|
||||
ProcessSim<Qop>(sim, comment, false, suffix);
|
||||
sim = getTraceSimulator(true);
|
||||
if (smart_wide)
|
||||
{
|
||||
var res = QTests.AES.SmartWideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128*pairs, false), nBits(128*pairs, false), pairs, Nr, Nk, in_place_mixcolumn, free_swaps).Result;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
res = QTests.AES.SmartWideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128*pairs, false), nBits(128*pairs, false), pairs, Nr, Nk, in_place_mixcolumn, widest, free_swaps).Result;
|
||||
ProcessSim<Qop>(sim, comment, true);
|
||||
}
|
||||
// public static void WideGroverOracle<Qop>(string comment = "", int Nr = 10, int Nk = 4, bool free_swaps = true, string suffix = "")
|
||||
// {
|
||||
// var sim = getTraceSimulator(false);
|
||||
// var res = QTests.AES.WideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128, false), nBits(128, false), Nr, Nk, free_swaps).Result;
|
||||
// ProcessSim<Qop>(sim, comment, false, suffix);
|
||||
// sim = getTraceSimulator(true);
|
||||
// res = QTests.AES.WideGroverOracle.Run(sim, nQBits(32*Nk, false), nQBits(128, false), nBits(128, false), Nr, Nk, free_swaps).Result;
|
||||
// ProcessSim<Qop>(sim, comment, true);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
583
aes/LPS19.qs
583
aes/LPS19.qs
|
@ -11,341 +11,342 @@ namespace LPS19
|
|||
{
|
||||
body (...)
|
||||
{
|
||||
CNOT(u[0], u[5]);
|
||||
CNOT(u[3], u[5]);
|
||||
CNOT(u[6], u[5]);
|
||||
CNOT(u[0], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[6], u[4]);
|
||||
LPAND(u[5], u[4], t[0], costing);
|
||||
CNOT(t[0], t[5]);
|
||||
use andAnc = Qubit[41] {
|
||||
CNOT(u[0], u[5]);
|
||||
CNOT(u[3], u[5]);
|
||||
CNOT(u[6], u[5]);
|
||||
CNOT(u[0], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[6], u[4]);
|
||||
LPANDWithAux(u[5], u[4], t[0], andAnc[0], costing);
|
||||
CNOT(t[0], t[5]);
|
||||
|
||||
CNOT(u[1], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[7], u[3]);
|
||||
LPAND(u[3], u[7], t[0], costing);
|
||||
CNOT(u[1], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[7], u[3]);
|
||||
LPANDWithAux(u[3], u[7], t[0], andAnc[1], costing);
|
||||
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[0], u[2]);
|
||||
CNOT(u[4], u[2]);
|
||||
CNOT(u[5], u[2]);
|
||||
CNOT(u[6], u[2]);
|
||||
LPAND(u[6], u[2], t[1], costing);
|
||||
CNOT(t[1], t[2]);
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[0], u[2]);
|
||||
CNOT(u[4], u[2]);
|
||||
CNOT(u[5], u[2]);
|
||||
CNOT(u[6], u[2]);
|
||||
LPANDWithAux(u[6], u[2], t[1], andAnc[2], costing);
|
||||
CNOT(t[1], t[2]);
|
||||
|
||||
CNOT(u[2], u[1]);
|
||||
CNOT(u[4], u[1]);
|
||||
CNOT(u[5], u[1]);
|
||||
CNOT(u[7], u[1]);
|
||||
CNOT(u[1], u[0]);
|
||||
CNOT(u[6], u[0]);
|
||||
LPAND(u[1], u[0], t[1], costing);
|
||||
CNOT(u[2], u[1]);
|
||||
CNOT(u[4], u[1]);
|
||||
CNOT(u[5], u[1]);
|
||||
CNOT(u[7], u[1]);
|
||||
CNOT(u[1], u[0]);
|
||||
CNOT(u[6], u[0]);
|
||||
LPANDWithAux(u[1], u[0], t[1], andAnc[3], costing);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[0], u[2]);
|
||||
LPAND(u[6], u[2], t[2], costing);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[0], u[2]);
|
||||
LPANDWithAux(u[6], u[2], t[2], andAnc[4], costing);
|
||||
|
||||
CNOT(u[6], u[3]);
|
||||
CNOT(u[7], u[2]);
|
||||
LPAND(u[3], u[2], t[3], costing);
|
||||
CNOT(t[3], t[4]);
|
||||
CNOT(u[6], u[3]);
|
||||
CNOT(u[7], u[2]);
|
||||
LPANDWithAux(u[3], u[2], t[3], andAnc[5], costing);
|
||||
CNOT(t[3], t[4]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[2], u[0]);
|
||||
CNOT(u[4], u[0]);
|
||||
CNOT(u[7], u[0]);
|
||||
LPAND(u[6], u[0], t[3], costing);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[2], u[0]);
|
||||
CNOT(u[4], u[0]);
|
||||
CNOT(u[7], u[0]);
|
||||
LPANDWithAux(u[6], u[0], t[3], andAnc[6], costing);
|
||||
|
||||
CNOT(u[6], u[3]);
|
||||
CNOT(u[2], u[0]);
|
||||
LPAND(u[3], u[0], t[4], costing);
|
||||
CNOT(u[6], u[3]);
|
||||
CNOT(u[2], u[0]);
|
||||
LPANDWithAux(u[3], u[0], t[4], andAnc[7], costing);
|
||||
|
||||
CNOT(t[3], t[1]);
|
||||
CNOT(t[3], t[1]);
|
||||
|
||||
CNOT(u[1], u[3]);
|
||||
CNOT(u[7], u[4]);
|
||||
LPAND(u[3], u[4], t[5], costing);
|
||||
CNOT(u[1], u[3]);
|
||||
CNOT(u[7], u[4]);
|
||||
LPANDWithAux(u[3], u[4], t[5], andAnc[8], costing);
|
||||
|
||||
CNOT(t[5], t[3]);
|
||||
CNOT(t[5], t[3]);
|
||||
|
||||
CNOT(t[4], t[0]);
|
||||
CNOT(t[4], t[0]);
|
||||
|
||||
CNOT(t[2], t[4]);
|
||||
CNOT(t[2], t[4]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[6], t[3]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[6], t[3]);
|
||||
|
||||
CNOT(u[0], u[1]);
|
||||
CNOT(u[3], u[1]);
|
||||
CNOT(u[1], t[0]);
|
||||
CNOT(u[0], u[1]);
|
||||
CNOT(u[3], u[1]);
|
||||
CNOT(u[1], t[0]);
|
||||
|
||||
CNOT(u[1], u[5]);
|
||||
CNOT(u[4], u[5]);
|
||||
CNOT(u[6], u[5]);
|
||||
CNOT(u[7], u[5]);
|
||||
CNOT(u[5], t[1]);
|
||||
CNOT(u[1], u[5]);
|
||||
CNOT(u[4], u[5]);
|
||||
CNOT(u[6], u[5]);
|
||||
CNOT(u[7], u[5]);
|
||||
CNOT(u[5], t[1]);
|
||||
|
||||
CNOT(u[1], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[5], u[4]);
|
||||
CNOT(u[4], t[4]);
|
||||
CNOT(u[1], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[5], u[4]);
|
||||
CNOT(u[4], t[4]);
|
||||
|
||||
LPAND(t[3], t[1], t[6], costing);
|
||||
CNOT(t[0], t[3]);
|
||||
LPANDWithAux(t[3], t[1], t[6], andAnc[9], costing);
|
||||
CNOT(t[0], t[3]);
|
||||
|
||||
CNOT(t[4], t[7]);
|
||||
CNOT(t[6], t[7]);
|
||||
CNOT(t[4], t[7]);
|
||||
CNOT(t[6], t[7]);
|
||||
|
||||
CNOT(t[0], t[6]);
|
||||
LPAND(t[3], t[7], t[0], costing);
|
||||
CNOT(t[0], t[6]);
|
||||
LPANDWithAux(t[3], t[7], t[0], andAnc[10], costing);
|
||||
|
||||
CNOT(t[1], t[8]);
|
||||
CNOT(t[4], t[8]);
|
||||
CNOT(t[1], t[8]);
|
||||
CNOT(t[4], t[8]);
|
||||
|
||||
LPAND(t[6], t[8], t[9], costing);
|
||||
LPANDWithAux(t[6], t[8], t[9], andAnc[11], costing);
|
||||
|
||||
|
||||
CNOT(t[4], t[8]);
|
||||
CNOT(t[1], t[8]);
|
||||
CNOT(t[4], t[8]);
|
||||
CNOT(t[1], t[8]);
|
||||
|
||||
|
||||
CNOT(t[4], t[9]);
|
||||
CNOT(t[9], t[1]);
|
||||
CNOT(t[4], t[9]);
|
||||
CNOT(t[9], t[1]);
|
||||
|
||||
CNOT(t[7], t[8]);
|
||||
CNOT(t[9], t[8]);
|
||||
CNOT(t[7], t[8]);
|
||||
CNOT(t[9], t[8]);
|
||||
|
||||
LPAND(t[4], t[8], t[10], costing);
|
||||
LPANDWithAux(t[4], t[8], t[10], andAnc[12], costing);
|
||||
|
||||
|
||||
CNOT(t[9], t[8]);
|
||||
CNOT(t[7], t[8]);
|
||||
CNOT(t[9], t[8]);
|
||||
CNOT(t[7], t[8]);
|
||||
|
||||
|
||||
CNOT(t[10], t[1]);
|
||||
CNOT(t[10], t[7]);
|
||||
LPAND(t[0], t[7], t[3], costing);
|
||||
CNOT(t[10], t[1]);
|
||||
CNOT(t[10], t[7]);
|
||||
LPANDWithAux(t[0], t[7], t[3], andAnc[13], costing);
|
||||
|
||||
CNOT(t[3], t[8]);
|
||||
CNOT(t[1], t[8]);
|
||||
CNOT(t[3], t[8]);
|
||||
CNOT(t[1], t[8]);
|
||||
|
||||
CNOT(t[0], t[11]);
|
||||
CNOT(t[9], t[11]);
|
||||
CNOT(t[0], t[11]);
|
||||
CNOT(t[9], t[11]);
|
||||
|
||||
|
||||
CNOT(t[0], t[12]);
|
||||
CNOT(t[3], t[12]);
|
||||
CNOT(t[0], t[12]);
|
||||
CNOT(t[3], t[12]);
|
||||
|
||||
CNOT(t[9], t[13]);
|
||||
CNOT(t[1], t[13]);
|
||||
CNOT(t[9], t[13]);
|
||||
CNOT(t[1], t[13]);
|
||||
|
||||
CNOT(t[11], t[14]);
|
||||
CNOT(t[8], t[14]);
|
||||
CNOT(t[11], t[14]);
|
||||
CNOT(t[8], t[14]);
|
||||
|
||||
CNOT(u[0], u[2]);
|
||||
CNOT(u[1], u[2]);
|
||||
CNOT(u[6], u[2]);
|
||||
CNOT(u[0], u[2]);
|
||||
CNOT(u[1], u[2]);
|
||||
CNOT(u[6], u[2]);
|
||||
|
||||
CNOT(u[1], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[5], u[4]);
|
||||
CNOT(u[1], u[4]);
|
||||
CNOT(u[3], u[4]);
|
||||
CNOT(u[5], u[4]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[7], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[7], u[6]);
|
||||
|
||||
CNOT(u[1], u[0]);
|
||||
CNOT(u[3], u[0]);
|
||||
CNOT(u[1], u[0]);
|
||||
CNOT(u[3], u[0]);
|
||||
|
||||
CNOT(u[0], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[6], u[3]);
|
||||
CNOT(u[0], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[6], u[3]);
|
||||
|
||||
LPAND(t[0], u[3], s[2], costing);
|
||||
CNOT(s[2], s[5]);
|
||||
|
||||
CNOT(u[0], u[3]);
|
||||
LPAND(t[12], u[3], s[6], costing);
|
||||
CNOT(s[6], s[2]);
|
||||
CNOT(s[6], s[5]);
|
||||
CNOT(u[0], u[3]);
|
||||
|
||||
LPAND(t[1], u[4], s[1], costing);
|
||||
CNOT(s[1], s[3]);
|
||||
CNOT(s[1], s[4]);
|
||||
CNOT(u[7], u[4]);
|
||||
LPAND(t[13], u[4], s[7], costing);
|
||||
CNOT(s[7], s[1]);
|
||||
CNOT(s[7], s[2]);
|
||||
CNOT(s[7], s[3]);
|
||||
CNOT(s[7], s[5]);
|
||||
CNOT(u[7], u[4]);
|
||||
|
||||
LPAND(t[3], u[0], s[6], costing);
|
||||
CNOT(s[6], s[7]);
|
||||
|
||||
CNOT(u[3], u[6]);
|
||||
LPAND(t[11], u[6], s[0], costing);
|
||||
CNOT(s[0], s[2]);
|
||||
CNOT(u[3], u[6]);
|
||||
|
||||
LPAND(t[14], u[2], s[0], costing);
|
||||
CNOT(s[0], s[1]);
|
||||
CNOT(s[0], s[3]);
|
||||
CNOT(s[0], s[4]);
|
||||
CNOT(s[0], s[5]);
|
||||
CNOT(s[0], s[6]);
|
||||
CNOT(s[0], s[7]);
|
||||
|
||||
LPAND(t[9], u[7], z[0], costing);
|
||||
CNOT(z[0], s[2]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[7]);
|
||||
LPAND(t[9], u[7], z[0], costing);
|
||||
|
||||
CNOT(u[0], u[5]);
|
||||
CNOT(u[3], u[5]);
|
||||
LPAND(t[12], u[5], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[7]);
|
||||
|
||||
LPAND(t[12], u[5], z[0], costing);
|
||||
CNOT(u[3], u[5]);
|
||||
CNOT(u[0], u[5]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
LPAND(t[3], u[6], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPAND(t[3], u[6], z[0], costing);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
LPAND(t[0], u[6], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[6]);
|
||||
CNOT(z[0], s[7]);
|
||||
|
||||
LPAND(t[0], u[6], z[0], costing);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[0], u[6]);
|
||||
|
||||
CNOT(u[0], u[7]);
|
||||
CNOT(u[1], u[7]);
|
||||
CNOT(u[2], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[6], u[7]);
|
||||
LPAND(t[11], u[7], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[2]);
|
||||
|
||||
LPAND(t[11], u[7], z[0], costing);
|
||||
CNOT(u[6], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[2], u[7]);
|
||||
CNOT(u[1], u[7]);
|
||||
CNOT(u[0], u[7]);
|
||||
|
||||
CNOT(u[0], u[7]);
|
||||
CNOT(u[3], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
LPAND(t[14], u[7], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPAND(t[14], u[7], z[0], costing);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[3], u[7]);
|
||||
CNOT(u[0], u[7]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPAND(t[8], u[6], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[2]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPAND(t[8], u[6], z[0], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
|
||||
CNOT(u[0], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
LPAND(t[13], u[3], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
|
||||
LPAND(t[13], u[3], z[0], costing);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[0], u[3]);
|
||||
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPAND(t[1], u[6], z[0], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
|
||||
LPAND(t[1], u[6], z[0], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[0], u[6]);
|
||||
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPAND(t[8], u[6], s[2], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
|
||||
LPAND(t[9], u[6], s[5], costing);
|
||||
LPANDWithAux(t[0], u[3], s[2], andAnc[14], costing);
|
||||
CNOT(s[2], s[5]);
|
||||
|
||||
CNOT(u[0], u[3]);
|
||||
LPANDWithAux(t[12], u[3], s[6], andAnc[15], costing);
|
||||
CNOT(s[6], s[2]);
|
||||
CNOT(s[6], s[5]);
|
||||
CNOT(u[0], u[3]);
|
||||
|
||||
LPANDWithAux(t[1], u[4], s[1], andAnc[16], costing);
|
||||
CNOT(s[1], s[3]);
|
||||
CNOT(s[1], s[4]);
|
||||
CNOT(u[7], u[4]);
|
||||
LPANDWithAux(t[13], u[4], s[7], andAnc[17], costing);
|
||||
CNOT(s[7], s[1]);
|
||||
CNOT(s[7], s[2]);
|
||||
CNOT(s[7], s[3]);
|
||||
CNOT(s[7], s[5]);
|
||||
CNOT(u[7], u[4]);
|
||||
|
||||
LPANDWithAux(t[3], u[0], s[6], andAnc[18], costing);
|
||||
CNOT(s[6], s[7]);
|
||||
|
||||
CNOT(u[3], u[6]);
|
||||
LPANDWithAux(t[11], u[6], s[0], andAnc[19], costing);
|
||||
CNOT(s[0], s[2]);
|
||||
CNOT(u[3], u[6]);
|
||||
|
||||
LPANDWithAux(t[14], u[2], s[0], andAnc[20], costing);
|
||||
CNOT(s[0], s[1]);
|
||||
CNOT(s[0], s[3]);
|
||||
CNOT(s[0], s[4]);
|
||||
CNOT(s[0], s[5]);
|
||||
CNOT(s[0], s[6]);
|
||||
CNOT(s[0], s[7]);
|
||||
|
||||
LPANDWithAux(t[9], u[7], z[0], andAnc[21], costing);
|
||||
CNOT(z[0], s[2]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[7]);
|
||||
LPANDWithAux(t[9], u[7], z[0], andAnc[22], costing);
|
||||
|
||||
CNOT(u[0], u[5]);
|
||||
CNOT(u[3], u[5]);
|
||||
LPANDWithAux(t[12], u[5], z[0], andAnc[23], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[7]);
|
||||
|
||||
LPANDWithAux(t[12], u[5], z[0], andAnc[24], costing);
|
||||
CNOT(u[3], u[5]);
|
||||
CNOT(u[0], u[5]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
LPANDWithAux(t[3], u[6], z[0], andAnc[25], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPANDWithAux(t[3], u[6], z[0], andAnc[26], costing);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[5], u[6]);
|
||||
LPANDWithAux(t[0], u[6], z[0], andAnc[27], costing);
|
||||
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[6]);
|
||||
CNOT(z[0], s[7]);
|
||||
|
||||
LPANDWithAux(t[0], u[6], z[0], andAnc[28], costing);
|
||||
CNOT(u[5], u[6]);
|
||||
CNOT(u[4], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[0], u[6]);
|
||||
|
||||
CNOT(u[0], u[7]);
|
||||
CNOT(u[1], u[7]);
|
||||
CNOT(u[2], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[6], u[7]);
|
||||
LPANDWithAux(t[11], u[7], z[0], andAnc[29], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[2]);
|
||||
|
||||
LPANDWithAux(t[11], u[7], z[0], andAnc[30], costing);
|
||||
CNOT(u[6], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[2], u[7]);
|
||||
CNOT(u[1], u[7]);
|
||||
CNOT(u[0], u[7]);
|
||||
|
||||
CNOT(u[0], u[7]);
|
||||
CNOT(u[3], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[5], u[7]);
|
||||
LPANDWithAux(t[14], u[7], z[0], andAnc[31], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPANDWithAux(t[14], u[7], z[0], andAnc[32], costing);
|
||||
CNOT(u[5], u[7]);
|
||||
CNOT(u[4], u[7]);
|
||||
CNOT(u[3], u[7]);
|
||||
CNOT(u[0], u[7]);
|
||||
|
||||
CNOT(u[1], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPANDWithAux(t[8], u[6], z[0], andAnc[33], costing);
|
||||
|
||||
CNOT(z[0], s[2]);
|
||||
CNOT(z[0], s[5]);
|
||||
CNOT(z[0], s[6]);
|
||||
|
||||
LPANDWithAux(t[8], u[6], z[0], andAnc[34], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[1], u[6]);
|
||||
|
||||
CNOT(u[0], u[3]);
|
||||
CNOT(u[2], u[3]);
|
||||
LPANDWithAux(t[13], u[3], z[0], andAnc[35], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
|
||||
LPANDWithAux(t[13], u[3], z[0], andAnc[36], costing);
|
||||
CNOT(u[2], u[3]);
|
||||
CNOT(u[0], u[3]);
|
||||
|
||||
CNOT(u[0], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPANDWithAux(t[1], u[6], z[0], andAnc[37], costing);
|
||||
|
||||
CNOT(z[0], s[0]);
|
||||
CNOT(z[0], s[1]);
|
||||
CNOT(z[0], s[3]);
|
||||
CNOT(z[0], s[4]);
|
||||
CNOT(z[0], s[5]);
|
||||
|
||||
LPANDWithAux(t[1], u[6], z[0], andAnc[38], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[0], u[6]);
|
||||
|
||||
CNOT(u[2], u[6]);
|
||||
CNOT(u[3], u[6]);
|
||||
LPANDWithAux(t[8], u[6], s[2], andAnc[39], costing);
|
||||
CNOT(u[3], u[6]);
|
||||
CNOT(u[2], u[6]);
|
||||
|
||||
LPANDWithAux(t[9], u[6], s[5], andAnc[40], costing);
|
||||
}
|
||||
X(s[1]);
|
||||
X(s[2]);
|
||||
X(s[6]);
|
||||
|
|
550
aes/QAES.qs
550
aes/QAES.qs
|
@ -4,17 +4,32 @@ namespace QAES
|
|||
{
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
open QUtilities;
|
||||
open Microsoft.Quantum.Arrays;
|
||||
|
||||
operation ByteSub(input_state: Qubit[][], ancilla: Qubit[][], costing: Bool) : Unit
|
||||
|
||||
|
||||
function ParitionByteSubAncilla(qubits: Qubit[]) : Qubit[][][] {
|
||||
let a = Most(Partitioned([129*4, size = 4], qubits));
|
||||
return Mapped(PartitionSubByteAncilla(_), a);
|
||||
}
|
||||
|
||||
operation ByteSub(input_state: Qubit[][], ancilla: Qubit[][], byteSubAnc: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
let ancLength = Length(byteSubAnc)/16;
|
||||
let byteSubAncArray1 = Most(Partitioned([ancLength*4, size=4], byteSubAnc));
|
||||
let byteSubAncArray = Mapped(Partitioned([ancLength, size=4], _), byteSubAncArray1);
|
||||
for i in 0..3
|
||||
{
|
||||
for j in 0..3
|
||||
{
|
||||
// GLRS16.SBox(input_state[j][(i*8)..((i+1)*8-1)], ancilla[j][(i*8)..((i+1)*8-1)], costing);
|
||||
BoyarPeralta11.SBox(input_state[j][(i*8)..((i+1)*8-1)], ancilla[j][(i*8)..((i+1)*8-1)], costing);
|
||||
BoyarPeralta11.SBox(
|
||||
input_state[j][(i*8)..((i+1)*8-1)],
|
||||
ancilla[j][(i*8)..((i+1)*8-1)],
|
||||
byteSubAncArray[j][i],
|
||||
costing);
|
||||
// BoyarPeralta11.AdjointInverseSBox(input_state[j][(i*8)..((i+1)*8-1)], ancilla[j][(i*8)..((i+1)*8-1)], costing);
|
||||
}
|
||||
}
|
||||
|
@ -22,14 +37,24 @@ namespace QAES
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation SubByte(input_word: Qubit[], ancilla: Qubit[], costing: Bool) : Unit
|
||||
function PartitionSubByteAncilla(qubits: Qubit[]) : Qubit[][] {
|
||||
return Most(Partitioned([129,size=4],qubits));
|
||||
}
|
||||
operation SubByte(input_word: Qubit[], ancilla: Qubit[], subByteAnc: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
let ancLength = Length(subByteAnc)/4;
|
||||
let subByteAncArray = Most(Partitioned([ancLength, size=4], subByteAnc));
|
||||
// Allocate all ancilla beforehand
|
||||
for i in 0..3
|
||||
{
|
||||
// GLRS16.SBox(input_word[(i*8)..((i+1)*8-1)], ancilla[(i*8)..((i+1)*8-1)], costing);
|
||||
BoyarPeralta11.SBox(input_word[(i*8)..((i+1)*8-1)], ancilla[(i*8)..((i+1)*8-1)], costing);
|
||||
BoyarPeralta11.SBox(
|
||||
input_word[(i*8)..((i+1)*8-1)],
|
||||
ancilla[(i*8)..((i+1)*8-1)],
|
||||
subByteAncArray[i],
|
||||
costing);
|
||||
// BoyarPeralta11.AdjointInverseSBox(input_word[(i*8)..((i+1)*8-1)], ancilla[(i*8)..((i+1)*8-1)], costing);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +65,7 @@ namespace QAES
|
|||
namespace QAES.Widest
|
||||
{
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
open Microsoft.Quantum.Arrays;
|
||||
open QUtilities;
|
||||
operation AddRoundKey(state: Qubit[][], round_key: Qubit[]) : Unit
|
||||
{
|
||||
|
@ -56,12 +82,68 @@ namespace QAES.Widest
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
|
||||
function NumberOfKeyExpansionSubBytes(Nr: Int, Nk: Int) : Int {
|
||||
mutable counter = 0;
|
||||
for i in Nk..(4*(Nr+1) - 1) {
|
||||
if (i % Nk != 0 and (i % Nk != 4 or Nk <= 6))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i % Nk == 0) // note this branch is executed less often when Nk = 6 than when Nk = 4, lowering the overal cost
|
||||
{
|
||||
|
||||
set counter = counter + 1;
|
||||
|
||||
}
|
||||
elif (Nk > 6 and i % Nk == 4)
|
||||
{
|
||||
set counter = counter + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
// Partitions qubit array in an accessible way
|
||||
function PartitionKeyExpansionSubBytes(Nr: Int, Nk: Int, qubits : Qubit[]) : Qubit[][] {
|
||||
mutable result = [[], size = 4*(Nr+1)];
|
||||
mutable counter = 0;
|
||||
let nSBAnc = 4*BoyarPeralta11.SBoxAncCount();
|
||||
for i in Nk..(4*(Nr+1) - 1) {
|
||||
if (i % Nk != 0 and (i % Nk != 4 or Nk <= 6))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i % Nk == 0) // note this branch is executed less often when Nk = 6 than when Nk = 4, lowering the overal cost
|
||||
{
|
||||
|
||||
set result w/= i <- qubits[counter*nSBAnc..(counter+1)*nSBAnc - 1];
|
||||
set counter = counter + 1;
|
||||
|
||||
}
|
||||
elif (Nk > 6 and i % Nk == 4)
|
||||
{
|
||||
// W[i] = SubByte(W[i-1]);
|
||||
set result w/= i <- qubits[counter*nSBAnc..(counter+1)*nSBAnc - 1];
|
||||
set counter = counter + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// WIDE version, does expand the whole key at the beginning
|
||||
// assumes the key is set to Zero, except for the first 4 * Nk bytes
|
||||
operation KeyExpansion(key: Qubit[], Nr: Int, Nk: Int, costing: Bool) : Unit
|
||||
operation KeyExpansion(key: Qubit[], Nr: Int, Nk: Int, subByteAncAll: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
// let subByteAnc = PartitionKeyExpansionSubBytes(Nr, Nk, subByteAncAll);
|
||||
// First stage of exapnsion is copying the AES key into the expanded key
|
||||
// this is unneded, we just allocate qubits for the whole expanded key
|
||||
// and load the block key in the first registers.
|
||||
|
@ -92,7 +174,7 @@ namespace QAES.Widest
|
|||
|
||||
// W[i] = SubByte(RotByte(W[i-1]))
|
||||
QAES.InPlace.RotByte(key[((i-1)*32 + 0)..((i-1)*32 + 31)], costing);
|
||||
QAES.SubByte(key[((i-1)*32 + 0)..((i-1)*32 + 31)], key[(i*32)..((i+1)*32-1)], costing);
|
||||
QAES.SubByte(key[((i-1)*32 + 0)..((i-1)*32 + 31)], key[(i*32)..((i+1)*32-1)], [], costing);
|
||||
(Adjoint QAES.InPlace.RotByte)(key[((i-1)*32 + 0)..((i-1)*32 + 31)], costing);
|
||||
|
||||
// W[i] ^^^= Rcon[i/Nk]; where uint8_t Rcon[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
|
@ -121,7 +203,7 @@ namespace QAES.Widest
|
|||
elif (Nk > 6 and i % Nk == 4)
|
||||
{
|
||||
// W[i] = SubByte(W[i-1]);
|
||||
QAES.SubByte(key[(i-1)*32..((i)*32-1)], key[i*32..((i+1)*32-1)], costing);
|
||||
QAES.SubByte(key[(i-1)*32..((i)*32-1)], key[i*32..((i+1)*32-1)], [], costing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,11 +218,11 @@ namespace QAES.Widest
|
|||
}
|
||||
|
||||
// round values start from 1 to Nr-1, since the final round Nr has a different shape
|
||||
operation Round(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], round: Int, costing: Bool) : Unit
|
||||
operation Round(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], byteSubAnc: Qubit[], round: Int, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
QAES.ByteSub(in_state, out_state, costing);
|
||||
QAES.ByteSub(in_state, out_state, byteSubAnc, costing);
|
||||
QAES.InPlace.ShiftRow(out_state, costing);
|
||||
QAES.InPlace.MixColumn(out_state, costing);
|
||||
AddRoundKey(out_state, key[(4*(round)*32)..(4*(round+1)*32-1)]);
|
||||
|
@ -148,11 +230,11 @@ namespace QAES.Widest
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation FinalRound(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], Nr: Int, costing: Bool) : Unit
|
||||
operation FinalRound(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], byteSubAnc: Qubit[], Nr: Int, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
QAES.ByteSub(in_state, out_state, costing);
|
||||
QAES.ByteSub(in_state, out_state, byteSubAnc, costing);
|
||||
QAES.InPlace.ShiftRow(out_state, costing);
|
||||
AddRoundKey(out_state, key[(4*(Nr)*32)..(4*(Nr+1)*32-1)]);
|
||||
}
|
||||
|
@ -163,11 +245,13 @@ namespace QAES.Widest
|
|||
// WIDE version
|
||||
// assumes the expanded_key is set to Zero, except for the first 4 * Nk bytes
|
||||
// assumes the state is set to Zero, except for the first 4 words containing the message
|
||||
operation ForwardRijndael(expanded_key: Qubit[], state: Qubit[], ciphertext: Qubit[], Nr: Int, Nk: Int, costing: Bool) : Unit
|
||||
operation ForwardRijndael(expanded_key: Qubit[], state: Qubit[], ciphertext: Qubit[], subByteAnc: Qubit[], byteSubAncAll : Qubit[], Nr: Int, Nk: Int, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
KeyExpansion(expanded_key, Nr, Nk, costing);
|
||||
let nBSAnc = 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
let byteSubAnc = Partitioned([nBSAnc, size=Nr], byteSubAncAll);
|
||||
KeyExpansion(expanded_key, Nr, Nk, subByteAnc, costing);
|
||||
|
||||
// "round 0"
|
||||
AddRoundKey([
|
||||
|
@ -190,7 +274,7 @@ namespace QAES.Widest
|
|||
state[(4*32*i + 1*32)..(4*32*i + 2*32 - 1)],
|
||||
state[(4*32*i + 2*32)..(4*32*i + 3*32 - 1)],
|
||||
state[(4*32*i + 3*32)..(4*32*i + 4*32 - 1)]
|
||||
], expanded_key, i, costing);
|
||||
], expanded_key, byteSubAnc[i], i, costing);
|
||||
}
|
||||
|
||||
// final round
|
||||
|
@ -204,7 +288,7 @@ namespace QAES.Widest
|
|||
state[(4*32*Nr + 1*32)..(4*32*Nr + 2*32 - 1)],
|
||||
state[(4*32*Nr + 2*32)..(4*32*Nr + 3*32 - 1)],
|
||||
state[(4*32*Nr + 3*32)..(4*32*Nr + 4*32 - 1)]
|
||||
], expanded_key, Nr, costing);
|
||||
], expanded_key, byteSubAnc[Nr-1], Nr, costing);
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
@ -213,35 +297,72 @@ namespace QAES.Widest
|
|||
{
|
||||
body (...)
|
||||
{
|
||||
ForwardRijndael(expanded_key, state, ciphertext, Nr, Nk, costing);
|
||||
let nSBAnc = 4*BoyarPeralta11.SBoxAncCount();
|
||||
let nBSAnc = 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
let nBSAncAll = Nr*nBSAnc;
|
||||
let nSBAncAll = NumberOfKeyExpansionSubBytes(Nr, Nk)*nSBAnc;
|
||||
use (sbAncAll, bSAncAll) = (Qubit[nSBAncAll], Qubit[nBSAncAll]) {
|
||||
// use (sbAnc2, bSAncAll2) = (Qubit[nSBAnc], Qubit[nBSAncAll]) {
|
||||
ForwardRijndael(expanded_key, state, ciphertext, sbAncAll, bSAncAll, Nr, Nk, costing);
|
||||
|
||||
// copy resulting ciphertext out
|
||||
for j in 0..3
|
||||
{
|
||||
CNOTBytes(state[(4*32*Nr + j*32)..(4*32*Nr + j*32 + 7)], ciphertext[(j*32 + 0)..(j*32 + 7)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 8)..(4*32*Nr + j*32 + 15)], ciphertext[(j*32 + 8)..(j*32 + 15)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 16)..(4*32*Nr + j*32 + 23)], ciphertext[(j*32 + 16)..(j*32 + 23)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 24)..(4*32*Nr + j*32 + 31)], ciphertext[(j*32 + 24)..(j*32 + 31)]);
|
||||
// copy resulting ciphertext out
|
||||
for j in 0..3
|
||||
{
|
||||
CNOTBytes(state[(4*32*Nr + j*32)..(4*32*Nr + j*32 + 7)], ciphertext[(j*32 + 0)..(j*32 + 7)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 8)..(4*32*Nr + j*32 + 15)], ciphertext[(j*32 + 8)..(j*32 + 15)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 16)..(4*32*Nr + j*32 + 23)], ciphertext[(j*32 + 16)..(j*32 + 23)]);
|
||||
CNOTBytes(state[(4*32*Nr + j*32 + 24)..(4*32*Nr + j*32 + 31)], ciphertext[(j*32 + 24)..(j*32 + 31)]);
|
||||
}
|
||||
|
||||
(Adjoint ForwardRijndael)(expanded_key, state, ciphertext, sbAncAll, bSAncAll, Nr, Nk, costing);
|
||||
// }
|
||||
}
|
||||
|
||||
(Adjoint ForwardRijndael)(expanded_key, state, ciphertext, Nr, Nk, costing);
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation GroverOracle(key_superposition: Qubit[], success: Qubit, plaintext: Qubit[], target_ciphertext: Bool[], Nr: Int, Nk: Int, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
// (state, expanded_key, ciphertext) = ( Qubit[4*32*(Nr+1)], Qubit[4*32*(Nr+1)], Qubit[4*32])
|
||||
// (key, success, plaintext) = (Qubit[Nk*32], Qubit(), Qubit[128*pairs])
|
||||
|
||||
|
||||
use (other_keys, other_state) = (Qubit[4*32*(Nr+1) - Nk*32], Qubit[4*32*(Nr+1) - 128])
|
||||
{
|
||||
|
||||
let nSBAnc = 4*BoyarPeralta11.SBoxAncCount();
|
||||
let nBSAnc = 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
let nBSAncAll = Nr*nBSAnc;
|
||||
let nSBAncAll = NumberOfKeyExpansionSubBytes(Nr, Nk)*nSBAnc;
|
||||
use (sbAncAll, bSAncAll) = (Qubit[nSBAncAll], Qubit[nBSAncAll]) {
|
||||
let state = plaintext + other_state;
|
||||
ForwardRijndael(key_superposition + other_keys, state, [], sbAncAll, bSAncAll, Nr, Nk, costing);
|
||||
let ciphertext = state[4*32*Nr..4*32*Nr+128-1];
|
||||
|
||||
CompareQubitstring(success, ciphertext, target_ciphertext, costing);
|
||||
|
||||
(Adjoint ForwardRijndael)(key_superposition + other_keys, state, [], sbAncAll, bSAncAll, Nr, Nk, costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace QAES.SmartWide
|
||||
{
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Arrays;
|
||||
open QUtilities;
|
||||
|
||||
// round values start from 1 to Nr-1, since the final round Nr has a different shape
|
||||
operation Round(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], round: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
operation Round(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], subByteAnc: Qubit[], byteSubAnc: Qubit[], round: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
QAES.ByteSub(in_state, out_state[0..3], costing);
|
||||
QAES.ByteSub(in_state, out_state[0..3], byteSubAnc, costing);
|
||||
QAES.InPlace.ShiftRow(out_state, costing);
|
||||
if (in_place_mixcolumn)
|
||||
{
|
||||
|
@ -255,7 +376,7 @@ namespace QAES.SmartWide
|
|||
if (Nk == 4)
|
||||
{
|
||||
// AES128
|
||||
QAES.InPlace.KeyExpansion(key, round, Nk, 0, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, round, Nk, 0, Nk-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state[(0 + (in_place_mixcolumn ? 0 | 4))..(3 + (in_place_mixcolumn ? 0 | 4))], key);
|
||||
}
|
||||
elif (Nk == 6)
|
||||
|
@ -267,9 +388,9 @@ namespace QAES.SmartWide
|
|||
let key_round = (round/3) * 2 + 1;
|
||||
if (round > 1)
|
||||
{
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 2*Nk/3, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 2*Nk/3, Nk-1, subByteAnc, costing);
|
||||
}
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, 1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, 1, subByteAnc, costing);
|
||||
CNOTnBits(key[4*32..(5*32-1)], out_state[0 + (in_place_mixcolumn ? 0 | 4)], 32);
|
||||
CNOTnBits(key[5*32..(6*32-1)], out_state[1 + (in_place_mixcolumn ? 0 | 4)], 32);
|
||||
CNOTnBits(key[0*32..(1*32-1)], out_state[2 + (in_place_mixcolumn ? 0 | 4)], 32);
|
||||
|
@ -278,13 +399,13 @@ namespace QAES.SmartWide
|
|||
elif (round % 3 == 2)
|
||||
{
|
||||
let key_round = (round/3) * 2 + 1;
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 2, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 2, Nk-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state[(0 + (in_place_mixcolumn ? 0 | 4))..(3 + (in_place_mixcolumn ? 0 | 4))], key[2*32..(6*32-1)]);
|
||||
}
|
||||
else
|
||||
{
|
||||
let key_round = (round/3) * 2;
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, 2*Nk/3-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, 2*Nk/3-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state[(0 + (in_place_mixcolumn ? 0 | 4))..(3 + (in_place_mixcolumn ? 0 | 4))], key[0*32..(4*32-1)]);
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +415,7 @@ namespace QAES.SmartWide
|
|||
if (round % 2 == 0)
|
||||
{
|
||||
let key_round = round/2;
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk/2-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk/2-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state[(0 + (in_place_mixcolumn ? 0 | 4))..(3 + (in_place_mixcolumn ? 0 | 4))], key[0*32..(4*32-1)]);
|
||||
}
|
||||
else
|
||||
|
@ -302,7 +423,7 @@ namespace QAES.SmartWide
|
|||
if (round > 2)
|
||||
{
|
||||
let key_round = round/2;
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, Nk/2, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, Nk/2, Nk-1, subByteAnc, costing);
|
||||
}
|
||||
QAES.Widest.AddRoundKey(out_state[(0 + (in_place_mixcolumn ? 0 | 4))..(3 + (in_place_mixcolumn ? 0 | 4))], key[4*32..(8*32-1)]);
|
||||
}
|
||||
|
@ -311,18 +432,18 @@ namespace QAES.SmartWide
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation FinalRound(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], round: Int, Nk: Int, costing: Bool) : Unit
|
||||
operation FinalRound(in_state: Qubit[][], out_state: Qubit[][], key: Qubit[], subByteAnc: Qubit[], byteSubAnc: Qubit[], round: Int, Nk: Int, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
QAES.ByteSub(in_state, out_state, costing);
|
||||
QAES.ByteSub(in_state, out_state, byteSubAnc, costing);
|
||||
QAES.InPlace.ShiftRow(out_state, costing);
|
||||
if (Nk == 4)
|
||||
{
|
||||
// AES128
|
||||
// Nk == Nb, so can simply run a round of key expansion
|
||||
// for every round of AES
|
||||
QAES.InPlace.KeyExpansion(key, round, Nk, 0, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, round, Nk, 0, Nk-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state, key);
|
||||
}
|
||||
elif (Nk == 6)
|
||||
|
@ -330,7 +451,7 @@ namespace QAES.SmartWide
|
|||
// AES192
|
||||
let key_round = (round/3) * 2;
|
||||
// note, need only first 4 words of last key round
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk-3, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk-3, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state, key[0*32..(4*32-1)]);
|
||||
}
|
||||
elif (Nk == 8)
|
||||
|
@ -338,104 +459,201 @@ namespace QAES.SmartWide
|
|||
// AES256
|
||||
// note, need only first 4 words of last key round
|
||||
let key_round = round/2;
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk/2-1, costing);
|
||||
QAES.InPlace.KeyExpansion(key, key_round, Nk, 0, Nk/2-1, subByteAnc, costing);
|
||||
QAES.Widest.AddRoundKey(out_state, key[0*32..(4*32-1)]);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation ForwardRijndael(key: Qubit[], state: Qubit[], Nr: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
// "round 0"
|
||||
QAES.Widest.AddRoundKey([
|
||||
state[(0*32)..(1*32-1)],
|
||||
state[(1*32)..(2*32-1)],
|
||||
state[(2*32)..(3*32-1)],
|
||||
state[(3*32)..(4*32-1)]
|
||||
], key);
|
||||
|
||||
for i in 1..(Nr-1)
|
||||
{
|
||||
// round i \in [1..Nr-1]
|
||||
Round(in_place_mixcolumn ? [
|
||||
state[(4*32*(i-1) + 0*32)..(4*32*(i-1) + 1*32 - 1)],
|
||||
state[(4*32*(i-1) + 1*32)..(4*32*(i-1) + 2*32 - 1)],
|
||||
state[(4*32*(i-1) + 2*32)..(4*32*(i-1) + 3*32 - 1)],
|
||||
state[(4*32*(i-1) + 3*32)..(4*32*(i-1) + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(i-1) + 0*32)..(8*32*(i-1) + 1*32 - 1)],
|
||||
state[(8*32*(i-1) + 1*32)..(8*32*(i-1) + 2*32 - 1)],
|
||||
state[(8*32*(i-1) + 2*32)..(8*32*(i-1) + 3*32 - 1)],
|
||||
state[(8*32*(i-1) + 3*32)..(8*32*(i-1) + 4*32 - 1)]
|
||||
], in_place_mixcolumn ? [
|
||||
state[(4*32*i + 0*32)..(4*32*i + 1*32 - 1)],
|
||||
state[(4*32*i + 1*32)..(4*32*i + 2*32 - 1)],
|
||||
state[(4*32*i + 2*32)..(4*32*i + 3*32 - 1)],
|
||||
state[(4*32*i + 3*32)..(4*32*i + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(i-1) + 4*32)..(8*32*(i-1) + 5*32 - 1)],
|
||||
state[(8*32*(i-1) + 5*32)..(8*32*(i-1) + 6*32 - 1)],
|
||||
state[(8*32*(i-1) + 6*32)..(8*32*(i-1) + 7*32 - 1)],
|
||||
state[(8*32*(i-1) + 7*32)..(8*32*(i-1) + 8*32 - 1)],
|
||||
state[(8*32*(i-1) + 8*32)..(8*32*(i-1) + 9*32 - 1)],
|
||||
state[(8*32*(i-1) + 9*32)..(8*32*(i-1) + 10*32 - 1)],
|
||||
state[(8*32*(i-1) + 10*32)..(8*32*(i-1) + 11*32 - 1)],
|
||||
state[(8*32*(i-1) + 11*32)..(8*32*(i-1) + 12*32 - 1)]
|
||||
], key, i, Nk, in_place_mixcolumn, costing);
|
||||
function RijndaelByteSubAncillaArranged(Nr: Int, Nk: Int, ancilla: Qubit[], widest: Bool) : Qubit[][] {
|
||||
if Nr == 10{ // AES-128
|
||||
return [ancilla, size = Nr];
|
||||
} elif Nr == 12 { // AES-192
|
||||
if widest {
|
||||
let nBSAnc = 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
let pair = [ancilla[0..nBSAnc-1],ancilla[nBSAnc..2*nBSAnc-1]];
|
||||
return Flattened([pair, size = Nr/2]);
|
||||
} else {
|
||||
return [ancilla, size = Nr];
|
||||
}
|
||||
|
||||
} else { // AES-256
|
||||
if widest {
|
||||
let nBSAnc = 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
let pair = [ancilla[0..nBSAnc-1],ancilla[nBSAnc..2*nBSAnc-1]];
|
||||
return Flattened([pair, size = Nr/2]);
|
||||
} else {
|
||||
return [ancilla, size = Nr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// final round
|
||||
FinalRound(in_place_mixcolumn ? [
|
||||
state[(4*32*(Nr-1) + 0*32)..(4*32*(Nr-1) + 1*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 1*32)..(4*32*(Nr-1) + 2*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 2*32)..(4*32*(Nr-1) + 3*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 3*32)..(4*32*(Nr-1) + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(Nr-1) + 0*32)..(8*32*(Nr-1) + 1*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 1*32)..(8*32*(Nr-1) + 2*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 2*32)..(8*32*(Nr-1) + 3*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 3*32)..(8*32*(Nr-1) + 4*32 - 1)]
|
||||
], in_place_mixcolumn ? [
|
||||
state[(4*32*Nr + 0*32)..(4*32*Nr + 1*32 - 1)],
|
||||
state[(4*32*Nr + 1*32)..(4*32*Nr + 2*32 - 1)],
|
||||
state[(4*32*Nr + 2*32)..(4*32*Nr + 3*32 - 1)],
|
||||
state[(4*32*Nr + 3*32)..(4*32*Nr + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(Nr-1) + 4*32)..(8*32*(Nr-1) + 5*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 5*32)..(8*32*(Nr-1) + 6*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 6*32)..(8*32*(Nr-1) + 7*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 7*32)..(8*32*(Nr-1) + 8*32 - 1)]
|
||||
],
|
||||
key, Nr, Nk, costing
|
||||
);
|
||||
function NumRijndaelByteSubAncilla(Nr: Int, Nk: Int, widest: Bool) : Int {
|
||||
if Nr == 10 { // AES-128
|
||||
return 4*4*BoyarPeralta11.SBoxAncCount();
|
||||
} elif Nr == 12 { // AES-192
|
||||
return (widest ? 2 | 1)*4*4*BoyarPeralta11.SBoxAncCount();
|
||||
} else { // AES-256
|
||||
return (widest ? 2 | 1)*4*4*BoyarPeralta11.SBoxAncCount();
|
||||
}
|
||||
}
|
||||
|
||||
function NumRijndaelSubBytesAncilla(Nr: Int, Nk: Int, widest: Bool) : Int {
|
||||
if Nk == 8 {
|
||||
return (widest ? 2 | 1)*4*BoyarPeralta11.SBoxAncCount();
|
||||
} elif Nk == 6 {
|
||||
return (widest ? 2 | 1)*4*BoyarPeralta11.SBoxAncCount();
|
||||
}else {
|
||||
return 4*BoyarPeralta11.SBoxAncCount();
|
||||
}
|
||||
}
|
||||
|
||||
function RijndaelSubByteAncillaArranged(Nr : Int, Nk: Int, ancilla: Qubit[], widest: Bool): Qubit[][] {
|
||||
if Nk == 8 {
|
||||
if widest {
|
||||
return [ancilla, size = Nr];
|
||||
// let nSBAnc = 4*BoyarPeralta11.SBoxAncCount();
|
||||
// let pair = [ancilla[0..nSBAnc-1],ancilla[nSBAnc..2*nSBAnc-1]];
|
||||
// return Flattened([pair, size = Nr/2]);
|
||||
} else {
|
||||
return [ancilla, size = Nr];
|
||||
}
|
||||
} elif Nk == 6 {
|
||||
if widest {
|
||||
let nSBAnc = 4*BoyarPeralta11.SBoxAncCount();
|
||||
let pair = Most(Partitioned([nSBAnc, size=2], ancilla));
|
||||
return Flattened([pair, size = Nr/2]);
|
||||
} else {
|
||||
return [ancilla, size=Nr];
|
||||
}
|
||||
} else {
|
||||
return [ancilla, size=Nr];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
operation ForwardRijndael(key: Qubit[], state: Qubit[], Nr: Int, Nk: Int, in_place_mixcolumn: Bool, ancilla: Qubit[], widest: Bool, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
let nBSAnc = NumRijndaelByteSubAncilla(Nr, Nk, widest);
|
||||
let nSBAnc = NumRijndaelSubBytesAncilla(Nr, Nk, widest);
|
||||
if Length(ancilla) < nBSAnc + nSBAnc {
|
||||
Message("Warning: not enough ancilla passed to Rijndael");
|
||||
let nExtra = nBSAnc + nSBAnc - Length(ancilla);
|
||||
use extraAnc = Qubit[nExtra] {
|
||||
ForwardRijndael(key, state, Nr, Nk, in_place_mixcolumn, ancilla+extraAnc, widest, costing);
|
||||
}
|
||||
} else {
|
||||
let byteSubAnc = RijndaelByteSubAncillaArranged(Nr, Nk, ancilla[0..nBSAnc-1], widest);
|
||||
let subByteAnc = RijndaelSubByteAncillaArranged(Nr, Nk, ancilla[nBSAnc..nBSAnc+nSBAnc-1], widest);
|
||||
// "round 0"
|
||||
QAES.Widest.AddRoundKey([
|
||||
state[(0*32)..(1*32-1)],
|
||||
state[(1*32)..(2*32-1)],
|
||||
state[(2*32)..(3*32-1)],
|
||||
state[(3*32)..(4*32-1)]
|
||||
], key);
|
||||
|
||||
for i in 1..(Nr-1)
|
||||
{
|
||||
// round i \in [1..Nr-1]
|
||||
Round(in_place_mixcolumn ? [
|
||||
state[(4*32*(i-1) + 0*32)..(4*32*(i-1) + 1*32 - 1)],
|
||||
state[(4*32*(i-1) + 1*32)..(4*32*(i-1) + 2*32 - 1)],
|
||||
state[(4*32*(i-1) + 2*32)..(4*32*(i-1) + 3*32 - 1)],
|
||||
state[(4*32*(i-1) + 3*32)..(4*32*(i-1) + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(i-1) + 0*32)..(8*32*(i-1) + 1*32 - 1)],
|
||||
state[(8*32*(i-1) + 1*32)..(8*32*(i-1) + 2*32 - 1)],
|
||||
state[(8*32*(i-1) + 2*32)..(8*32*(i-1) + 3*32 - 1)],
|
||||
state[(8*32*(i-1) + 3*32)..(8*32*(i-1) + 4*32 - 1)]
|
||||
], in_place_mixcolumn ? [
|
||||
state[(4*32*i + 0*32)..(4*32*i + 1*32 - 1)],
|
||||
state[(4*32*i + 1*32)..(4*32*i + 2*32 - 1)],
|
||||
state[(4*32*i + 2*32)..(4*32*i + 3*32 - 1)],
|
||||
state[(4*32*i + 3*32)..(4*32*i + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(i-1) + 4*32)..(8*32*(i-1) + 5*32 - 1)],
|
||||
state[(8*32*(i-1) + 5*32)..(8*32*(i-1) + 6*32 - 1)],
|
||||
state[(8*32*(i-1) + 6*32)..(8*32*(i-1) + 7*32 - 1)],
|
||||
state[(8*32*(i-1) + 7*32)..(8*32*(i-1) + 8*32 - 1)],
|
||||
state[(8*32*(i-1) + 8*32)..(8*32*(i-1) + 9*32 - 1)],
|
||||
state[(8*32*(i-1) + 9*32)..(8*32*(i-1) + 10*32 - 1)],
|
||||
state[(8*32*(i-1) + 10*32)..(8*32*(i-1) + 11*32 - 1)],
|
||||
state[(8*32*(i-1) + 11*32)..(8*32*(i-1) + 12*32 - 1)]
|
||||
], key, subByteAnc[i-1], byteSubAnc[i-1], i, Nk, in_place_mixcolumn, costing);
|
||||
}
|
||||
|
||||
// final round
|
||||
FinalRound(in_place_mixcolumn ? [
|
||||
state[(4*32*(Nr-1) + 0*32)..(4*32*(Nr-1) + 1*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 1*32)..(4*32*(Nr-1) + 2*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 2*32)..(4*32*(Nr-1) + 3*32 - 1)],
|
||||
state[(4*32*(Nr-1) + 3*32)..(4*32*(Nr-1) + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(Nr-1) + 0*32)..(8*32*(Nr-1) + 1*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 1*32)..(8*32*(Nr-1) + 2*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 2*32)..(8*32*(Nr-1) + 3*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 3*32)..(8*32*(Nr-1) + 4*32 - 1)]
|
||||
], in_place_mixcolumn ? [
|
||||
state[(4*32*Nr + 0*32)..(4*32*Nr + 1*32 - 1)],
|
||||
state[(4*32*Nr + 1*32)..(4*32*Nr + 2*32 - 1)],
|
||||
state[(4*32*Nr + 2*32)..(4*32*Nr + 3*32 - 1)],
|
||||
state[(4*32*Nr + 3*32)..(4*32*Nr + 4*32 - 1)]
|
||||
] | [
|
||||
state[(8*32*(Nr-1) + 4*32)..(8*32*(Nr-1) + 5*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 5*32)..(8*32*(Nr-1) + 6*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 6*32)..(8*32*(Nr-1) + 7*32 - 1)],
|
||||
state[(8*32*(Nr-1) + 7*32)..(8*32*(Nr-1) + 8*32 - 1)]
|
||||
],
|
||||
key, subByteAnc[Nr-1], byteSubAnc[Nr-1], Nr, Nk, costing
|
||||
);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation Rijndael(key: Qubit[], state: Qubit[], ciphertext: Qubit[], Nr: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
operation Rijndael(key: Qubit[], state: Qubit[], ciphertext: Qubit[], Nr: Int, Nk: Int, in_place_mixcolumn: Bool, widest: Bool, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
ForwardRijndael(key, state, Nr, Nk, in_place_mixcolumn, costing);
|
||||
let nAnc = NumRijndaelByteSubAncilla(Nr, Nk, widest) + NumRijndaelSubBytesAncilla(Nr, Nk, widest);
|
||||
use rijndaelAnc = Qubit[nAnc] {
|
||||
ForwardRijndael(key, state, Nr, Nk, in_place_mixcolumn, rijndaelAnc, widest, costing);
|
||||
|
||||
// copy resulting ciphertext out
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 0*32)..(4*32*Nr + 1*32 - 1)] | state[(8*32*(Nr-1) + 4*32)..(8*32*(Nr-1) + 5*32 - 1)], ciphertext[0..31], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 1*32)..(4*32*Nr + 2*32 - 1)] | state[(8*32*(Nr-1) + 5*32)..(8*32*(Nr-1) + 6*32 - 1)], ciphertext[32..63], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 2*32)..(4*32*Nr + 3*32 - 1)] | state[(8*32*(Nr-1) + 6*32)..(8*32*(Nr-1) + 7*32 - 1)], ciphertext[64..95], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 3*32)..(4*32*Nr + 4*32 - 1)] | state[(8*32*(Nr-1) + 7*32)..(8*32*(Nr-1) + 8*32 - 1)], ciphertext[96..127], 32);
|
||||
// copy resulting ciphertext out
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 0*32)..(4*32*Nr + 1*32 - 1)] | state[(8*32*(Nr-1) + 4*32)..(8*32*(Nr-1) + 5*32 - 1)], ciphertext[0..31], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 1*32)..(4*32*Nr + 2*32 - 1)] | state[(8*32*(Nr-1) + 5*32)..(8*32*(Nr-1) + 6*32 - 1)], ciphertext[32..63], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 2*32)..(4*32*Nr + 3*32 - 1)] | state[(8*32*(Nr-1) + 6*32)..(8*32*(Nr-1) + 7*32 - 1)], ciphertext[64..95], 32);
|
||||
CNOTnBits(in_place_mixcolumn ? state[(4*32*Nr + 3*32)..(4*32*Nr + 4*32 - 1)] | state[(8*32*(Nr-1) + 7*32)..(8*32*(Nr-1) + 8*32 - 1)], ciphertext[96..127], 32);
|
||||
|
||||
(Adjoint ForwardRijndael)(key, state, Nr, Nk, in_place_mixcolumn, costing);
|
||||
(Adjoint ForwardRijndael)(key, state, Nr, Nk, in_place_mixcolumn, rijndaelAnc, widest, costing);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation ForwardGroverOracle(other_keys: Qubit[], state_ancillas: Qubit[], key_superposition: Qubit[], success: Qubit, plaintext: Qubit[], target_ciphertext: Bool[], pairs: Int, Nr: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
operation ForwardGroverOracle(
|
||||
other_keys: Qubit[],
|
||||
state_ancillas: Qubit[],
|
||||
key_superposition: Qubit[],
|
||||
success: Qubit,
|
||||
plaintext: Qubit[],
|
||||
target_ciphertext: Bool[],
|
||||
pairs: Int,
|
||||
Nr: Int,
|
||||
Nk: Int,
|
||||
in_place_mixcolumn: Bool,
|
||||
ancilla: Qubit[],
|
||||
widest: Bool,
|
||||
costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
let nAnc = NumRijndaelByteSubAncilla(Nr, Nk, widest) + NumRijndaelSubBytesAncilla(Nr, Nk, widest);
|
||||
let ancArray = Partitioned([nAnc, size=pairs], ancilla);
|
||||
// copy loaded key
|
||||
for i in 0..(pairs-2)
|
||||
{
|
||||
|
@ -447,19 +665,20 @@ namespace QAES.SmartWide
|
|||
{
|
||||
let state = plaintext[(i*128)..((i+1)*128-1)] + (in_place_mixcolumn ? state_ancillas[(i*128*Nr)..((i+1)*128*Nr-1)] | state_ancillas[(i*128*(2*Nr-1))..((i+1)*128*(2*Nr-1)-1)]);
|
||||
let key = i == 0 ? key_superposition | other_keys[((i-1)*Nk*32)..(i*Nk*32-1)];
|
||||
ForwardRijndael(key, state, Nr, Nk, in_place_mixcolumn, costing);
|
||||
ForwardRijndael(key, state, Nr, Nk, in_place_mixcolumn, ancArray[i], widest, costing);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
operation GroverOracle(key_superposition: Qubit[], success: Qubit, plaintext: Qubit[], target_ciphertext: Bool[], pairs: Int, Nr: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Unit
|
||||
operation GroverOracle(key_superposition: Qubit[], success: Qubit, plaintext: Qubit[], target_ciphertext: Bool[], pairs: Int, Nr: Int, Nk: Int, in_place_mixcolumn: Bool, widest: Bool, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
use (other_keys, state_ancillas) = (Qubit[32*Nk*(pairs-1)], Qubit[128*(in_place_mixcolumn ? Nr | (2*Nr-1))*pairs])
|
||||
let nAnc = NumRijndaelByteSubAncilla(Nr, Nk, widest) + NumRijndaelSubBytesAncilla(Nr, Nk, widest);
|
||||
use (other_keys, state_ancillas, sBoxAnc) = (Qubit[32*Nk*(pairs-1)], Qubit[128*(in_place_mixcolumn ? Nr | (2*Nr-1))*pairs], Qubit[nAnc*pairs])
|
||||
{
|
||||
ForwardGroverOracle(other_keys, state_ancillas, key_superposition, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, costing);
|
||||
ForwardGroverOracle(other_keys, state_ancillas, key_superposition, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, sBoxAnc, widest, costing);
|
||||
|
||||
// debug output
|
||||
// for (i in 0..(Length(target_ciphertext)-1))
|
||||
|
@ -479,7 +698,7 @@ namespace QAES.SmartWide
|
|||
|
||||
CompareQubitstring(success, ciphertext, target_ciphertext, costing);
|
||||
|
||||
(Adjoint ForwardGroverOracle)(other_keys, state_ancillas, key_superposition, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, costing);
|
||||
(Adjoint ForwardGroverOracle)(other_keys, state_ancillas, key_superposition, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, sBoxAnc, widest, costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -852,50 +1071,75 @@ namespace QAES.InPlace
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation KeyExpansion(key: Qubit[], kexp_round: Int, Nk: Int, first_word: Int, last_word: Int, costing: Bool) : Unit
|
||||
|
||||
function KeyExpansionAncilla(Nk: Int, first_word: Int, last_word: Int, subByteAnc: Qubit[]) : Qubit[][] {
|
||||
if (Nk == 8){
|
||||
// If there aren't enough, re-use
|
||||
if Length(subByteAnc) < 8*BoyarPeralta11.SBoxAncCount() {
|
||||
return [subByteAnc[0..4*BoyarPeralta11.SBoxAncCount()-1], size = 2];
|
||||
} else {
|
||||
return [subByteAnc[0..4*BoyarPeralta11.SBoxAncCount()-1],subByteAnc[4*BoyarPeralta11.SBoxAncCount()..Length(subByteAnc)-1]];
|
||||
}
|
||||
} else {
|
||||
return [subByteAnc];
|
||||
}
|
||||
}
|
||||
|
||||
operation KeyExpansion(key: Qubit[], kexp_round: Int, Nk: Int, first_word: Int, last_word: Int, subByteAnc: Qubit[], costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
for i in first_word..last_word
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
RotByte(key[(32*(Nk-1))..(32*(Nk)-1)], costing);
|
||||
QAES.SubByte(key[(32*(Nk-1))..(32*(Nk)-1)], key[(32*(0))..(32*(1)-1)], costing);
|
||||
(Adjoint RotByte)(key[(32*(Nk-1))..(32*(Nk)-1)], costing);
|
||||
|
||||
// W[i] ^^^= Rcon[i/Nk]; where uint8_t Rcon[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
if (kexp_round > 0 and kexp_round < 9)
|
||||
{
|
||||
// flip the ((i/Nk)-1)-th bit
|
||||
X(key[kexp_round - 1]);
|
||||
}
|
||||
elif (kexp_round == 9)
|
||||
{
|
||||
// >>> bin(0x1b) == '0b00011011'
|
||||
X(key[0]);
|
||||
X(key[1]);
|
||||
X(key[3]);
|
||||
X(key[4]);
|
||||
}
|
||||
elif (kexp_round == 10)
|
||||
{
|
||||
// >>> bin(0x36) == '0b00110110'
|
||||
X(key[1]);
|
||||
X(key[2]);
|
||||
X(key[4]);
|
||||
X(key[5]);
|
||||
}
|
||||
{
|
||||
// Add extra qubits as necessary
|
||||
if Length(subByteAnc) < 4*BoyarPeralta11.SBoxAncCount() { //(Nk== 8 ? 8*BoyarPeralta11.SBoxAncCount() | 4*BoyarPeralta11.SBoxAncCount()) {
|
||||
let nExtra = (Nk== 8 ? 8*BoyarPeralta11.SBoxAncCount() | 4*BoyarPeralta11.SBoxAncCount()) - Length(subByteAnc);
|
||||
use extra = Qubit[nExtra] {
|
||||
KeyExpansion(key, kexp_round, Nk, first_word, last_word, subByteAnc + extra, costing);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
let subByteAncs = KeyExpansionAncilla(Nk, first_word, last_word, subByteAnc);
|
||||
for i in first_word..last_word
|
||||
{
|
||||
if (Nk == 8 and i == 4)
|
||||
if (i == 0)
|
||||
{
|
||||
QAES.SubByte(key[(32*(i-1))..(32*(i)-1)], key[(32*(i))..(32*(i+1)-1)], costing);
|
||||
RotByte(key[(32*(Nk-1))..(32*(Nk)-1)], costing);
|
||||
// QAES.SubByte(key[(32*(Nk-1))..(32*(Nk)-1)], key[(32*(0))..(32*(1)-1)], [], costing);
|
||||
QAES.SubByte(key[(32*(Nk-1))..(32*(Nk)-1)], key[(32*(0))..(32*(1)-1)], subByteAncs[0], costing);
|
||||
(Adjoint RotByte)(key[(32*(Nk-1))..(32*(Nk)-1)], costing);
|
||||
|
||||
// W[i] ^^^= Rcon[i/Nk]; where uint8_t Rcon[11] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
if (kexp_round > 0 and kexp_round < 9)
|
||||
{
|
||||
// flip the ((i/Nk)-1)-th bit
|
||||
X(key[kexp_round - 1]);
|
||||
}
|
||||
elif (kexp_round == 9)
|
||||
{
|
||||
// >>> bin(0x1b) == '0b00011011'
|
||||
X(key[0]);
|
||||
X(key[1]);
|
||||
X(key[3]);
|
||||
X(key[4]);
|
||||
}
|
||||
elif (kexp_round == 10)
|
||||
{
|
||||
// >>> bin(0x36) == '0b00110110'
|
||||
X(key[1]);
|
||||
X(key[2]);
|
||||
X(key[4]);
|
||||
X(key[5]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CNOTnBits(key[(32*(i-1))..(32*(i)-1)], key[(32*(i))..(32*(i+1)-1)], 32);
|
||||
if (Nk == 8 and i == 4)
|
||||
{
|
||||
// QAES.SubByte(key[(32*(i-1))..(32*(i)-1)], key[(32*(i))..(32*(i+1)-1)], [], costing);
|
||||
QAES.SubByte(key[(32*(i-1))..(32*(i)-1)], key[(32*(i))..(32*(i+1)-1)], subByteAncs[1], costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
CNOTnBits(key[(32*(i-1))..(32*(i)-1)], key[(32*(i))..(32*(i+1)-1)], 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
132
aes/QGF256.qs
132
aes/QGF256.qs
|
@ -22,7 +22,7 @@ namespace QGF256
|
|||
{
|
||||
for j in (i+1)..7
|
||||
{
|
||||
ccnot(a[j], b[8+i-j], res[i], costing);
|
||||
ccnot(a[j], b[8+i-j], res[i], [], costing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ namespace QGF256
|
|||
{
|
||||
for j in 0..i
|
||||
{
|
||||
ccnot(a[j], b[i-j], res[i], costing);
|
||||
ccnot(a[j], b[i-j], res[i], [], costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,40 +87,40 @@ namespace QGF256
|
|||
{
|
||||
// construct e
|
||||
|
||||
ccnot(a[1], b[7], res[0], costing);
|
||||
ccnot(a[2], b[6], res[0], costing);
|
||||
ccnot(a[3], b[5], res[0], costing);
|
||||
ccnot(a[4], b[4], res[0], costing);
|
||||
ccnot(a[5], b[3], res[0], costing);
|
||||
ccnot(a[6], b[2], res[0], costing);
|
||||
ccnot(a[7], b[1], res[0], costing);
|
||||
ccnot(a[1], b[7], res[0], [], costing);
|
||||
ccnot(a[2], b[6], res[0], [], costing);
|
||||
ccnot(a[3], b[5], res[0], [], costing);
|
||||
ccnot(a[4], b[4], res[0], [], costing);
|
||||
ccnot(a[5], b[3], res[0], [], costing);
|
||||
ccnot(a[6], b[2], res[0], [], costing);
|
||||
ccnot(a[7], b[1], res[0], [], costing);
|
||||
|
||||
ccnot(a[2], b[7], res[1], costing);
|
||||
ccnot(a[3], b[6], res[1], costing);
|
||||
ccnot(a[4], b[5], res[1], costing);
|
||||
ccnot(a[5], b[4], res[1], costing);
|
||||
ccnot(a[6], b[3], res[1], costing);
|
||||
ccnot(a[7], b[2], res[1], costing);
|
||||
ccnot(a[2], b[7], res[1], [], costing);
|
||||
ccnot(a[3], b[6], res[1], [], costing);
|
||||
ccnot(a[4], b[5], res[1], [], costing);
|
||||
ccnot(a[5], b[4], res[1], [], costing);
|
||||
ccnot(a[6], b[3], res[1], [], costing);
|
||||
ccnot(a[7], b[2], res[1], [], costing);
|
||||
|
||||
ccnot(a[3], b[7], res[2], costing);
|
||||
ccnot(a[4], b[6], res[2], costing);
|
||||
ccnot(a[5], b[5], res[2], costing);
|
||||
ccnot(a[6], b[4], res[2], costing);
|
||||
ccnot(a[7], b[3], res[2], costing);
|
||||
ccnot(a[3], b[7], res[2], [], costing);
|
||||
ccnot(a[4], b[6], res[2], [], costing);
|
||||
ccnot(a[5], b[5], res[2], [], costing);
|
||||
ccnot(a[6], b[4], res[2], [], costing);
|
||||
ccnot(a[7], b[3], res[2], [], costing);
|
||||
|
||||
ccnot(a[4], b[7], res[3], costing);
|
||||
ccnot(a[5], b[6], res[3], costing);
|
||||
ccnot(a[6], b[5], res[3], costing);
|
||||
ccnot(a[7], b[4], res[3], costing);
|
||||
ccnot(a[4], b[7], res[3], [], costing);
|
||||
ccnot(a[5], b[6], res[3], [], costing);
|
||||
ccnot(a[6], b[5], res[3], [], costing);
|
||||
ccnot(a[7], b[4], res[3], [], costing);
|
||||
|
||||
ccnot(a[5], b[7], res[4], costing);
|
||||
ccnot(a[6], b[6], res[4], costing);
|
||||
ccnot(a[7], b[5], res[4], costing);
|
||||
ccnot(a[5], b[7], res[4], [], costing);
|
||||
ccnot(a[6], b[6], res[4], [], costing);
|
||||
ccnot(a[7], b[5], res[4], [], costing);
|
||||
|
||||
ccnot(a[6], b[7], res[5], costing);
|
||||
ccnot(a[7], b[6], res[5], costing);
|
||||
ccnot(a[6], b[7], res[5], [], costing);
|
||||
ccnot(a[7], b[6], res[5], [], costing);
|
||||
|
||||
ccnot(a[7], b[7], res[6], costing);
|
||||
ccnot(a[7], b[7], res[6], [], costing);
|
||||
|
||||
// do modulo reduction
|
||||
// U
|
||||
|
@ -158,49 +158,49 @@ namespace QGF256
|
|||
|
||||
// compute d
|
||||
|
||||
ccnot(a[0], b[7], res[7], costing);
|
||||
ccnot(a[1], b[6], res[7], costing);
|
||||
ccnot(a[2], b[5], res[7], costing);
|
||||
ccnot(a[3], b[4], res[7], costing);
|
||||
ccnot(a[4], b[3], res[7], costing);
|
||||
ccnot(a[5], b[2], res[7], costing);
|
||||
ccnot(a[6], b[1], res[7], costing);
|
||||
ccnot(a[7], b[0], res[7], costing);
|
||||
ccnot(a[0], b[7], res[7], [], costing);
|
||||
ccnot(a[1], b[6], res[7], [], costing);
|
||||
ccnot(a[2], b[5], res[7], [], costing);
|
||||
ccnot(a[3], b[4], res[7], [], costing);
|
||||
ccnot(a[4], b[3], res[7], [], costing);
|
||||
ccnot(a[5], b[2], res[7], [], costing);
|
||||
ccnot(a[6], b[1], res[7], [], costing);
|
||||
ccnot(a[7], b[0], res[7], [], costing);
|
||||
|
||||
ccnot(a[0], b[6], res[6], costing);
|
||||
ccnot(a[1], b[5], res[6], costing);
|
||||
ccnot(a[2], b[4], res[6], costing);
|
||||
ccnot(a[3], b[3], res[6], costing);
|
||||
ccnot(a[4], b[2], res[6], costing);
|
||||
ccnot(a[5], b[1], res[6], costing);
|
||||
ccnot(a[6], b[0], res[6], costing);
|
||||
ccnot(a[0], b[6], res[6], [], costing);
|
||||
ccnot(a[1], b[5], res[6], [], costing);
|
||||
ccnot(a[2], b[4], res[6], [], costing);
|
||||
ccnot(a[3], b[3], res[6], [], costing);
|
||||
ccnot(a[4], b[2], res[6], [], costing);
|
||||
ccnot(a[5], b[1], res[6], [], costing);
|
||||
ccnot(a[6], b[0], res[6], [], costing);
|
||||
|
||||
ccnot(a[0], b[5], res[5], costing);
|
||||
ccnot(a[1], b[4], res[5], costing);
|
||||
ccnot(a[2], b[3], res[5], costing);
|
||||
ccnot(a[3], b[2], res[5], costing);
|
||||
ccnot(a[4], b[1], res[5], costing);
|
||||
ccnot(a[5], b[0], res[5], costing);
|
||||
ccnot(a[0], b[5], res[5], [], costing);
|
||||
ccnot(a[1], b[4], res[5], [], costing);
|
||||
ccnot(a[2], b[3], res[5], [], costing);
|
||||
ccnot(a[3], b[2], res[5], [], costing);
|
||||
ccnot(a[4], b[1], res[5], [], costing);
|
||||
ccnot(a[5], b[0], res[5], [], costing);
|
||||
|
||||
ccnot(a[0], b[4], res[4], costing);
|
||||
ccnot(a[1], b[3], res[4], costing);
|
||||
ccnot(a[2], b[2], res[4], costing);
|
||||
ccnot(a[3], b[1], res[4], costing);
|
||||
ccnot(a[4], b[0], res[4], costing);
|
||||
ccnot(a[0], b[4], res[4], [], costing);
|
||||
ccnot(a[1], b[3], res[4], [], costing);
|
||||
ccnot(a[2], b[2], res[4], [], costing);
|
||||
ccnot(a[3], b[1], res[4], [], costing);
|
||||
ccnot(a[4], b[0], res[4], [], costing);
|
||||
|
||||
ccnot(a[0], b[3], res[3], costing);
|
||||
ccnot(a[1], b[2], res[3], costing);
|
||||
ccnot(a[2], b[1], res[3], costing);
|
||||
ccnot(a[3], b[0], res[3], costing);
|
||||
ccnot(a[0], b[3], res[3], [], costing);
|
||||
ccnot(a[1], b[2], res[3], [], costing);
|
||||
ccnot(a[2], b[1], res[3], [], costing);
|
||||
ccnot(a[3], b[0], res[3], [], costing);
|
||||
|
||||
ccnot(a[0], b[2], res[2], costing);
|
||||
ccnot(a[1], b[1], res[2], costing);
|
||||
ccnot(a[2], b[0], res[2], costing);
|
||||
ccnot(a[0], b[2], res[2], [], costing);
|
||||
ccnot(a[1], b[1], res[2], [], costing);
|
||||
ccnot(a[2], b[0], res[2], [], costing);
|
||||
|
||||
ccnot(a[0], b[1], res[1], costing);
|
||||
ccnot(a[1], b[0], res[1], costing);
|
||||
ccnot(a[0], b[1], res[1], [], costing);
|
||||
ccnot(a[1], b[0], res[1], [], costing);
|
||||
|
||||
ccnot(a[0], b[0], res[0], costing);
|
||||
ccnot(a[0], b[0], res[0], [], costing);
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
|
123
aes/QTests.qs
123
aes/QTests.qs
|
@ -7,6 +7,29 @@ namespace QTests.GF256
|
|||
open Microsoft.Quantum.Convert;
|
||||
open QUtilities;
|
||||
|
||||
operation MeasureDepth() : Unit {
|
||||
use qubits = Qubit[5] {
|
||||
H(qubits[0]);
|
||||
T(qubits[0]);
|
||||
// let m = M(qubits[0]);
|
||||
let m = Measure([PauliZ, size= 5], qubits);
|
||||
// Microsoft.Quantum.Diagnostics.AssertMeasurementProbability([PauliZ], [qubits[0]], Zero, 0.5, "", 1e-10);
|
||||
|
||||
if m == One {
|
||||
T(qubits[1]);
|
||||
} else {
|
||||
T(qubits[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operation TestAllOnes(n: Int, costing: Bool) : Unit {
|
||||
use (qubits, target) = (Qubit[n], Qubit()) {
|
||||
TestIfAllOnes(qubits, target, costing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
operation Inverse(_a: Result[], costing: Bool) : Result[]
|
||||
{
|
||||
mutable res = [Zero, size = 8];
|
||||
|
@ -246,8 +269,8 @@ namespace QTests.AES
|
|||
else
|
||||
{
|
||||
if (tower_field)
|
||||
{
|
||||
BoyarPeralta11.SBox(a, b, costing);
|
||||
{
|
||||
BoyarPeralta11.SBox(a, b, [], costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,9 +491,9 @@ namespace QTests.AES
|
|||
Set(_input_state[j * 32 + i], input_state[j][i]);
|
||||
}
|
||||
}
|
||||
|
||||
QAES.ByteSub(input_state, output_state, costing);
|
||||
|
||||
use sBAnc = Qubit[4*4*BoyarPeralta11.SBoxAncCount()]{
|
||||
QAES.ByteSub(input_state, output_state, sBAnc, costing);
|
||||
}
|
||||
for i in 0..31
|
||||
{
|
||||
set res_1 w/= i <- M(output_state[0][i]);
|
||||
|
@ -574,9 +597,9 @@ namespace QTests.AES
|
|||
{
|
||||
Set(_key[i], key[i]);
|
||||
}
|
||||
|
||||
QAES.Widest.KeyExpansion(key, Nr, Nk, costing);
|
||||
|
||||
use sbAnc = Qubit[QAES.Widest.NumberOfKeyExpansionSubBytes(Nr, Nk)*4*BoyarPeralta11.SBoxAncCount()]{
|
||||
QAES.Widest.KeyExpansion(key, Nr, Nk, sbAnc, costing);
|
||||
}
|
||||
for i in 0..(32*4*(Nr+1)-1)
|
||||
{
|
||||
set res w/= i <- M(key[i]);
|
||||
|
@ -602,7 +625,8 @@ namespace QTests.AES
|
|||
Set(_key[i], key[i]);
|
||||
}
|
||||
|
||||
QAES.InPlace.KeyExpansion(key, kexp_round, Nk, low, high, costing);
|
||||
|
||||
QAES.InPlace.KeyExpansion(key, kexp_round, Nk, low, high, [], costing);
|
||||
|
||||
for i in 0..(32*4*(Nr+1)-1)
|
||||
{
|
||||
|
@ -633,8 +657,8 @@ namespace QTests.AES
|
|||
let key_rounds = (Nr+1)*4/Nk;
|
||||
for round in 1..key_rounds
|
||||
{
|
||||
QAES.InPlace.KeyExpansion(temp, round, Nk, 0, Nk/2, costing);
|
||||
QAES.InPlace.KeyExpansion(temp, round, Nk, Nk/2+1, Nk-1, costing);
|
||||
QAES.InPlace.KeyExpansion(temp, round, Nk, 0, Nk/2, [], costing);
|
||||
QAES.InPlace.KeyExpansion(temp, round, Nk, Nk/2+1, Nk-1, [], costing);
|
||||
if (round < key_rounds)
|
||||
{
|
||||
CNOTnBits(temp, key[round*Nk*32..((round+1)*Nk*32-1)], Nk*32);
|
||||
|
@ -692,17 +716,19 @@ namespace QTests.AES
|
|||
Set(_round_key[j * 32 + i], round_key[32*j + i]);
|
||||
}
|
||||
}
|
||||
use sBAnc = Qubit[4*4*BoyarPeralta11.SBoxAncCount()]{
|
||||
|
||||
if (smart_wide)
|
||||
{
|
||||
QAES.SmartWide.Round(in_state, out_state, round_key, round, Nk, in_place_mixcolumn, costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
// note in the test we use "round 0", but in practice
|
||||
// "round 0" consists only in copying the initial 4 words
|
||||
// of the expanded key onto the message, before starting rounds
|
||||
QAES.Widest.Round(in_state, out_state[4..7], round_key, 0, costing);
|
||||
if (smart_wide)
|
||||
{
|
||||
QAES.SmartWide.Round(in_state, out_state, round_key, [], sBAnc, round, Nk, in_place_mixcolumn, costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
// note in the test we use "round 0", but in practice
|
||||
// "round 0" consists only in copying the initial 4 words
|
||||
// of the expanded key onto the message, before starting rounds
|
||||
QAES.Widest.Round(in_state, out_state[4..7], round_key, sBAnc, 0, costing);
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..31
|
||||
|
@ -767,14 +793,15 @@ namespace QTests.AES
|
|||
Set(_round_key[j * 32 + i], round_key[4*32*Nr + 32*j + i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (smart_wide)
|
||||
{
|
||||
QAES.SmartWide.FinalRound(in_state, out_state, round_key, Nr, Nr - 6, costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
QAES.Widest.FinalRound(in_state, out_state, round_key, Nr, costing);
|
||||
use sBAnc = Qubit[4*4*BoyarPeralta11.SBoxAncCount()]{
|
||||
if (smart_wide)
|
||||
{
|
||||
QAES.SmartWide.FinalRound(in_state, out_state, round_key,[], sBAnc, Nr, Nr - 6, costing);
|
||||
}
|
||||
else
|
||||
{
|
||||
QAES.Widest.FinalRound(in_state, out_state, round_key, sBAnc, Nr, costing);
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..31
|
||||
|
@ -904,7 +931,7 @@ namespace QTests.AES
|
|||
}
|
||||
}
|
||||
|
||||
QAES.SmartWide.Rijndael(key, state, ciphertext, Nr, Nk, in_place_mixcolumn, costing);
|
||||
QAES.SmartWide.Rijndael(key, state, ciphertext, Nr, Nk, in_place_mixcolumn, false, costing);
|
||||
|
||||
for i in 0..31
|
||||
{
|
||||
|
@ -948,8 +975,40 @@ namespace QTests.AES
|
|||
}
|
||||
return [res_1, res_2, res_3, res_4];
|
||||
}
|
||||
// operation WideGroverOracle (_key: Result[], _plaintexts: Result[], target_ciphertext: Bool[], Nr: Int, Nk: Int, costing: Bool) : Result
|
||||
// {
|
||||
// mutable res = Zero;
|
||||
|
||||
operation SmartWideGroverOracle (_key: Result[], _plaintexts: Result[], target_ciphertext: Bool[], pairs: Int, Nr: Int, Nk: Int, in_place_mixcolumn: Bool, costing: Bool) : Result
|
||||
// use (key, success, plaintext) = (Qubit[Nk*32], Qubit(), Qubit[128])
|
||||
// {
|
||||
// for i in 0..(Nk*32-1)
|
||||
// {
|
||||
// Set(_key[i], key[i]);
|
||||
// }
|
||||
// for i in 0..127
|
||||
// {
|
||||
// Set(_plaintexts[i], plaintext[i]);
|
||||
// }
|
||||
|
||||
// // in actual use, we'd initialise set Success to |-), but not in this case
|
||||
// QAES.Widest.GroverOracle(key, success, plaintext, target_ciphertext, Nr, Nk, costing);
|
||||
|
||||
// set res = M(success);
|
||||
|
||||
// Set(Zero, success);
|
||||
// for i in 0..(Nk*32-1)
|
||||
// {
|
||||
// Set(Zero, key[i]);
|
||||
// }
|
||||
// for i in 0..127
|
||||
// {
|
||||
// Set(Zero, plaintext[i]);
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
operation SmartWideGroverOracle (_key: Result[], _plaintexts: Result[], target_ciphertext: Bool[], pairs: Int, Nr: Int, Nk: Int, in_place_mixcolumn: Bool, widest: Bool, costing: Bool) : Result
|
||||
{
|
||||
mutable res = Zero;
|
||||
|
||||
|
@ -968,7 +1027,7 @@ namespace QTests.AES
|
|||
}
|
||||
|
||||
// in actual use, we'd initialise set Success to |-), but not in this case
|
||||
QAES.SmartWide.GroverOracle(key, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, costing);
|
||||
QAES.SmartWide.GroverOracle(key, success, plaintext, target_ciphertext, pairs, Nr, Nk, in_place_mixcolumn, widest, costing);
|
||||
|
||||
set res = M(success);
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -6,6 +6,25 @@ namespace QUtilities
|
|||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Diagnostics;
|
||||
|
||||
|
||||
// Blocks operations from parallelizing through this point
|
||||
// i.e., forces mutual dependencies in the call graph
|
||||
// Ruins full depth and full gate counts
|
||||
operation Block(qubits: Qubit[]) : Unit {
|
||||
body (...) {
|
||||
for i in 0..Length(qubits) - 2 {
|
||||
CNOT(qubits[i],qubits[i+1]);
|
||||
}
|
||||
for i in Length(qubits) - 1..(-1)..1 {
|
||||
CNOT(qubits[i],qubits[i-1]);
|
||||
}
|
||||
}
|
||||
controlled (controls, ... ){
|
||||
Block(controls + qubits);
|
||||
}
|
||||
controlled adjoint auto;
|
||||
}
|
||||
|
||||
operation Set (desired: Result, q1: Qubit) : Unit {
|
||||
if (desired != M(q1)) {
|
||||
X(q1);
|
||||
|
@ -67,12 +86,12 @@ namespace QUtilities
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation ccnot(x: Qubit, y: Qubit, z: Qubit, costing: Bool) : Unit {
|
||||
operation ccnot(x: Qubit, y: Qubit, z: Qubit, anc: Qubit[], costing: Bool) : Unit {
|
||||
body (...)
|
||||
{
|
||||
if (costing)
|
||||
{
|
||||
ccnot_T_depth_1(x, y, z);
|
||||
ccnot_T_depth_1(x, y, z, anc);
|
||||
// ccnot_7_t_depth_4(x, y, z);
|
||||
}
|
||||
else
|
||||
|
@ -108,21 +127,44 @@ namespace QUtilities
|
|||
adjoint auto;
|
||||
}
|
||||
|
||||
operation LPAND (in_1: Qubit, in_2: Qubit, outp: Qubit, costing: Bool) : Unit
|
||||
{
|
||||
body (...)
|
||||
{
|
||||
if (costing)
|
||||
{
|
||||
AND(in_1, in_2, outp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ccnot does not assume output bit to be set to Zero!
|
||||
ccnot(in_1, in_2, outp, costing);
|
||||
|
||||
operation LPANDWithAux(control1: Qubit, control2: Qubit, target: Qubit, anc: Qubit, costing: Bool) : Unit {
|
||||
body (...) {
|
||||
if (costing){
|
||||
H(target);
|
||||
LinearPrepare(control1, control2, target, anc);
|
||||
Adjoint T(control1);
|
||||
Adjoint T(control2);
|
||||
T(target);
|
||||
T(anc);
|
||||
Adjoint LinearPrepare(control1, control2, target, anc);
|
||||
H(target);
|
||||
S(target);
|
||||
} else {
|
||||
ccnot(control1, control2, target, [anc], costing);
|
||||
}
|
||||
}
|
||||
adjoint auto;
|
||||
adjoint (...) {
|
||||
if (costing) {
|
||||
H(target);
|
||||
AssertMeasurementProbability([PauliZ], [target], One, 0.5, "Probability of the measurement must be 0.5", 1e-10);
|
||||
|
||||
if (IsResultOne(Measure([PauliZ, size=3], [control1, control2, target]))) {
|
||||
// Just do a C-Z?
|
||||
// Also no reason to reset the target; that's implied by measurement
|
||||
CZ(control1, control2);
|
||||
|
||||
// S(control1);
|
||||
// S(control2);
|
||||
// CNOT(control1, control2);
|
||||
// Adjoint S(control2);
|
||||
// CNOT(control1, control2);
|
||||
// X(target);
|
||||
}
|
||||
} else {
|
||||
ccnot(control1, control2, target, [anc], costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
@ -151,12 +193,20 @@ namespace QUtilities
|
|||
adjoint (...) {
|
||||
H(target);
|
||||
AssertMeasurementProbability([PauliZ], [target], One, 0.5, "Probability of the measurement must be 0.5", 1e-10);
|
||||
if (IsResultOne(M(target))) {
|
||||
S(control1);
|
||||
S(control2);
|
||||
CNOT(control1, control2);
|
||||
Adjoint S(control2);
|
||||
CNOT(control1, control2);
|
||||
|
||||
// Clumsy hack to escape the measurement-dependency bug
|
||||
Block([target, control1, control2]);
|
||||
|
||||
if (IsResultOne(Measure([PauliZ, size=3], [control1, control2, target]))) {
|
||||
// Just do a C-Z?
|
||||
CZ(control1, control2);
|
||||
|
||||
|
||||
// S(control1);
|
||||
// S(control2);
|
||||
// CNOT(control1, control2);
|
||||
// Adjoint S(control2);
|
||||
// CNOT(control1, control2);
|
||||
X(target);
|
||||
}
|
||||
}
|
||||
|
@ -210,15 +260,17 @@ namespace QUtilities
|
|||
// /// # See Also
|
||||
// /// - For the circuit diagram see Figure 1 on
|
||||
// /// [ Page 3 of arXiv:1210.0974v2 ](https://arxiv.org/pdf/1210.0974v2.pdf#page=2)
|
||||
operation ccnot_T_depth_1 (control1 : Qubit, control2 : Qubit, target : Qubit) : Unit is Adj + Ctl {
|
||||
use auxillaryRegister = Qubit[4] {
|
||||
|
||||
operation ccnot_T_depth_1 (control1 : Qubit, control2 : Qubit, target : Qubit, anc: Qubit[]) : Unit is Adj + Ctl {
|
||||
if Length(anc) < 4 {
|
||||
use aux = Qubit[4 - Length(anc)]{
|
||||
ccnot_T_depth_1(control1, control2, target, anc+aux);
|
||||
}
|
||||
} else {
|
||||
// apply UVU† where U is outer circuit and V is inner circuit
|
||||
ApplyWithCA(TDepthOneCCNOTOuterCircuit, TDepthOneCCNOTInnerCircuit, auxillaryRegister + [target, control1, control2]);
|
||||
ApplyWithCA(TDepthOneCCNOTOuterCircuit, TDepthOneCCNOTInnerCircuit, anc + [target, control1, control2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// # See Also
|
||||
/// - Used as a part of @"Microsoft.Quantum.Samples.UnitTesting.TDepthOneCCNOT"
|
||||
/// - For the circuit diagram see Figure 1 on
|
||||
|
@ -268,12 +320,12 @@ namespace QUtilities
|
|||
/// ancilla which are not uncomputed.
|
||||
/// If controlQubits has n qubits, then this needs n-2
|
||||
/// blankControlQubits.
|
||||
operation CompressControls(controlQubits : Qubit[], blankControlQubits : Qubit[], output : Qubit, costing: Bool) : Unit {
|
||||
operation CompressControls(controlQubits : Qubit[], blankControlQubits : Qubit[], output : Qubit, andAnc: Qubit[], costing: Bool) : Unit {
|
||||
body (...){
|
||||
let nControls = Length(controlQubits);
|
||||
let nNewControls = Length(blankControlQubits);
|
||||
if (nControls == 2){
|
||||
LPAND(controlQubits[0], controlQubits[1], output, costing);
|
||||
LPANDWithAux(controlQubits[0], controlQubits[1], output, andAnc[0], costing);
|
||||
} else {
|
||||
Fact(nNewControls >= nControls/2, $"Cannot compress {nControls}
|
||||
control qubits to {nNewControls} qubits without more ancilla");
|
||||
|
@ -282,12 +334,12 @@ namespace QUtilities
|
|||
{nNewControls} qubits because there are too few controls");
|
||||
let compressLength = nControls - nNewControls;
|
||||
for idx in 0.. 2 .. nControls - 2{
|
||||
LPAND(controlQubits[idx], controlQubits[idx + 1], blankControlQubits[idx/2], costing);
|
||||
LPANDWithAux(controlQubits[idx], controlQubits[idx + 1], blankControlQubits[idx/2], andAnc[idx/2], costing);
|
||||
}
|
||||
if (nControls % 2 == 0){
|
||||
CompressControls(blankControlQubits[0.. nControls/2 - 1], blankControlQubits[nControls/2 .. nNewControls - 1], output, costing);
|
||||
CompressControls(blankControlQubits[0.. nControls/2 - 1], blankControlQubits[nControls/2 .. nNewControls - 1], output, andAnc[(nControls)/2..Length(andAnc)-1], costing);
|
||||
} else {
|
||||
CompressControls([controlQubits[nControls - 1]] + blankControlQubits[0.. nControls/2 - 1], blankControlQubits[nControls/2 .. nNewControls - 1], output, costing);
|
||||
CompressControls([controlQubits[nControls - 1]] + blankControlQubits[0.. nControls/2 - 1], blankControlQubits[nControls/2 .. nNewControls - 1], output, andAnc[(nControls-1)/2..Length(andAnc)-1], costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,13 +365,13 @@ namespace QUtilities
|
|||
let nQubits = Length(xs);
|
||||
if (nQubits == 1){
|
||||
CNOT(xs[0], output);
|
||||
} elif (nQubits == 2){
|
||||
ccnot(xs[0], xs[1], output, costing);
|
||||
// } elif (nQubits == 2){
|
||||
// ccnot(xs[0], xs[1], output, costing);
|
||||
} else {
|
||||
use (spareControls, ancillaOutput) = (Qubit[nQubits - 2], Qubit()){
|
||||
CompressControls(xs, spareControls, ancillaOutput, costing);
|
||||
use (spareControls, ancillaOutput, andAnc) = (Qubit[nQubits - 2], Qubit(), Qubit[nQubits-1]){
|
||||
CompressControls(xs, spareControls, ancillaOutput, andAnc, costing);
|
||||
CNOT(ancillaOutput, output);
|
||||
(Adjoint CompressControls)(xs, spareControls, ancillaOutput, costing);
|
||||
(Adjoint CompressControls)(xs, spareControls, ancillaOutput, andAnc, costing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import qsharp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%qsharp\n",
|
||||
"\n",
|
||||
"operation SayHello(name : String) : Unit {\n",
|
||||
" Message($\"Hello, {name}!\");\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Hello, quantum world!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"SayHello.simulate(name=\"quantum world\");"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import qsharp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"\n",
|
||||
"%%qsharp\n",
|
||||
"\n",
|
||||
"operation SayHello(name : String) : Unit {\n",
|
||||
" Message($\"Hello, {name}!\");\n",
|
||||
"}\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"No such magic command %simulate_sparse.\n",
|
||||
"Possibly similar magic commands:\n",
|
||||
"- %simulate\n",
|
||||
"- %azure.status\n",
|
||||
"- %estimate\n",
|
||||
"To get a list of all available magic commands, run %lsmagic, or visit https://docs.microsoft.com/qsharp/api/iqsharp-magic/.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"SayHello.simulate_sparse(name = \"quantum world\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/json": {
|
||||
"cell": {
|
||||
"!": "OSMagics",
|
||||
"HTML": "Other",
|
||||
"SVG": "Other",
|
||||
"bash": "Other",
|
||||
"capture": "ExecutionMagics",
|
||||
"debug": "ExecutionMagics",
|
||||
"file": "Other",
|
||||
"html": "DisplayMagics",
|
||||
"javascript": "DisplayMagics",
|
||||
"js": "DisplayMagics",
|
||||
"latex": "DisplayMagics",
|
||||
"markdown": "DisplayMagics",
|
||||
"perl": "Other",
|
||||
"prun": "ExecutionMagics",
|
||||
"pypy": "Other",
|
||||
"python": "Other",
|
||||
"python2": "Other",
|
||||
"python3": "Other",
|
||||
"qsharp": "Other",
|
||||
"ruby": "Other",
|
||||
"script": "ScriptMagics",
|
||||
"sh": "Other",
|
||||
"svg": "DisplayMagics",
|
||||
"sx": "OSMagics",
|
||||
"system": "OSMagics",
|
||||
"time": "ExecutionMagics",
|
||||
"timeit": "ExecutionMagics",
|
||||
"writefile": "OSMagics"
|
||||
},
|
||||
"line": {
|
||||
"alias": "OSMagics",
|
||||
"alias_magic": "BasicMagics",
|
||||
"autoawait": "AsyncMagics",
|
||||
"autocall": "AutoMagics",
|
||||
"automagic": "AutoMagics",
|
||||
"autosave": "KernelMagics",
|
||||
"bookmark": "OSMagics",
|
||||
"cat": "Other",
|
||||
"cd": "OSMagics",
|
||||
"clear": "KernelMagics",
|
||||
"colors": "BasicMagics",
|
||||
"conda": "PackagingMagics",
|
||||
"config": "ConfigMagics",
|
||||
"connect_info": "KernelMagics",
|
||||
"cp": "Other",
|
||||
"debug": "ExecutionMagics",
|
||||
"dhist": "OSMagics",
|
||||
"dirs": "OSMagics",
|
||||
"doctest_mode": "BasicMagics",
|
||||
"ed": "Other",
|
||||
"edit": "KernelMagics",
|
||||
"env": "OSMagics",
|
||||
"gui": "BasicMagics",
|
||||
"hist": "Other",
|
||||
"history": "HistoryMagics",
|
||||
"killbgscripts": "ScriptMagics",
|
||||
"ldir": "Other",
|
||||
"less": "KernelMagics",
|
||||
"lf": "Other",
|
||||
"lk": "Other",
|
||||
"ll": "Other",
|
||||
"load": "CodeMagics",
|
||||
"load_ext": "ExtensionMagics",
|
||||
"loadpy": "CodeMagics",
|
||||
"logoff": "LoggingMagics",
|
||||
"logon": "LoggingMagics",
|
||||
"logstart": "LoggingMagics",
|
||||
"logstate": "LoggingMagics",
|
||||
"logstop": "LoggingMagics",
|
||||
"ls": "Other",
|
||||
"lsmagic": "BasicMagics",
|
||||
"lx": "Other",
|
||||
"macro": "ExecutionMagics",
|
||||
"magic": "BasicMagics",
|
||||
"man": "KernelMagics",
|
||||
"matplotlib": "PylabMagics",
|
||||
"mkdir": "Other",
|
||||
"more": "KernelMagics",
|
||||
"mv": "Other",
|
||||
"notebook": "BasicMagics",
|
||||
"page": "BasicMagics",
|
||||
"pastebin": "CodeMagics",
|
||||
"pdb": "ExecutionMagics",
|
||||
"pdef": "NamespaceMagics",
|
||||
"pdoc": "NamespaceMagics",
|
||||
"pfile": "NamespaceMagics",
|
||||
"pinfo": "NamespaceMagics",
|
||||
"pinfo2": "NamespaceMagics",
|
||||
"pip": "PackagingMagics",
|
||||
"popd": "OSMagics",
|
||||
"pprint": "BasicMagics",
|
||||
"precision": "BasicMagics",
|
||||
"prun": "ExecutionMagics",
|
||||
"psearch": "NamespaceMagics",
|
||||
"psource": "NamespaceMagics",
|
||||
"pushd": "OSMagics",
|
||||
"pwd": "OSMagics",
|
||||
"pycat": "OSMagics",
|
||||
"pylab": "PylabMagics",
|
||||
"qtconsole": "KernelMagics",
|
||||
"quickref": "BasicMagics",
|
||||
"recall": "HistoryMagics",
|
||||
"rehashx": "OSMagics",
|
||||
"reload_ext": "ExtensionMagics",
|
||||
"rep": "Other",
|
||||
"rerun": "HistoryMagics",
|
||||
"reset": "NamespaceMagics",
|
||||
"reset_selective": "NamespaceMagics",
|
||||
"rm": "Other",
|
||||
"rmdir": "Other",
|
||||
"run": "ExecutionMagics",
|
||||
"save": "CodeMagics",
|
||||
"sc": "OSMagics",
|
||||
"set_env": "OSMagics",
|
||||
"store": "StoreMagics",
|
||||
"sx": "OSMagics",
|
||||
"system": "OSMagics",
|
||||
"tb": "ExecutionMagics",
|
||||
"time": "ExecutionMagics",
|
||||
"timeit": "ExecutionMagics",
|
||||
"unalias": "OSMagics",
|
||||
"unload_ext": "ExtensionMagics",
|
||||
"who": "NamespaceMagics",
|
||||
"who_ls": "NamespaceMagics",
|
||||
"whos": "NamespaceMagics",
|
||||
"xdel": "NamespaceMagics",
|
||||
"xmode": "BasicMagics"
|
||||
}
|
||||
},
|
||||
"text/plain": [
|
||||
"Available line magics:\n",
|
||||
"%alias %alias_magic %autoawait %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %conda %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %pip %popd %pprint %precision %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode\n",
|
||||
"\n",
|
||||
"Available cell magics:\n",
|
||||
"%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%markdown %%perl %%prun %%pypy %%python %%python2 %%python3 %%qsharp %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile\n",
|
||||
"\n",
|
||||
"Automagic is ON, % prefix IS NOT needed for line magics."
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%lsmagic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "AttributeError",
|
||||
"evalue": "'QSharpCallable' object has no attribute 'simulate_dense'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-5-58385154ab68>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mSayHello\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate_dense\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"quantum world\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||
"\u001b[0;31mAttributeError\u001b[0m: 'QSharpCallable' object has no attribute 'simulate_dense'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"SayHello.simulate_dense(name = \"quantum world\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%%qsharp\n",
|
||||
"\n",
|
||||
"operation nop(): Unit {}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "AttributeError",
|
||||
"evalue": "'QSharpCallable' object has no attribute 'simulate_dense'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-10-c9837ab1e587>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mnop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mnop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate_dense\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||
"\u001b[0;31mAttributeError\u001b[0m: 'QSharpCallable' object has no attribute 'simulate_dense'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"nop.simulate()\n",
|
||||
"nop.simulate_dense()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "SyntaxError",
|
||||
"evalue": "invalid syntax (<ipython-input-11-eb0b1725da69>, line 1)",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-11-eb0b1725da69>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m qsharp version\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"qsharp version"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<!-- Copyright (c) Microsoft Corporation.
|
||||
Licensed under the MIT license. -->
|
||||
<Project Sdk="Microsoft.Quantum.Sdk/0.24.208024"><!--Microsoft.NET.Sdk">-->
|
||||
<Project Sdk="Microsoft.Quantum.Sdk/0.27.244707"><!--Microsoft.NET.Sdk"24.210930>-->
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
@ -10,7 +10,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FileHelpers" Version="3.4.1" />
|
||||
<PackageReference Include="Microsoft.Quantum.Standard" Version="0.24.201332" />
|
||||
<PackageReference Include="Microsoft.Quantum.Standard" Version="0.27.244707" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -512,7 +512,7 @@ class Tests:
|
|||
assert(res == [True] * trials)
|
||||
|
||||
@staticmethod
|
||||
def GroverOracle(smart_wide=True, Nr=10, Nk=4, pairs=1, in_place_mixcolumn=False, cost=False):
|
||||
def GroverOracle(smart_wide=True, Nr=10, Nk=4, pairs=1, in_place_mixcolumn=False, widest = False, cost=False):
|
||||
"""
|
||||
TEST:
|
||||
>>> Tests.GroverOracle(smart_wide=True, in_place_mixcolumn=False, Nr=10, Nk=4, pairs=1)
|
||||
|
@ -580,7 +580,7 @@ class Tests:
|
|||
if flip:
|
||||
qkey[0] = 0 if qkey[0] == 1 else 1
|
||||
|
||||
qgrover = GroverOracle.toffoli_simulate(_key=qkey, _plaintexts=qmessage, target_ciphertext=target_ciphertext, pairs=pairs, Nr=Nr, Nk=Nk, in_place_mixcolumn=in_place_mixcolumn, costing=False)
|
||||
qgrover = GroverOracle.toffoli_simulate(_key=qkey, _plaintexts=qmessage, target_ciphertext=target_ciphertext, pairs=pairs, Nr=Nr, Nk=Nk, in_place_mixcolumn=in_place_mixcolumn, widest = widest, costing=False)
|
||||
res.append(qgrover == int(not flip))
|
||||
assert(res == [True] * trials)
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// // Functions to run an operation several times and write timing data to a file or console
|
||||
|
||||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Runtime.InteropServices;
|
||||
// using System.Text;
|
||||
// using Microsoft.Quantum.Simulation.Simulators;
|
||||
// using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators;
|
||||
// using Microsoft.Quantum.Simulation.Core;
|
||||
// using Microsoft.Quantum.Canon;
|
||||
// using Microsoft.Quantum.Simulation.Simulators.QCTraceSimulators.Implementation;
|
||||
|
||||
// namespace Microsoft.Quantum.Canon
|
||||
// {
|
||||
// public partial class Touch
|
||||
// {
|
||||
// private QCTraceSimulator simulator;
|
||||
// public class Native : Touch
|
||||
// {
|
||||
// public Native(IOperationFactory m) : base(m)
|
||||
// {
|
||||
// simulator = m as QCTraceSimulator;
|
||||
// }
|
||||
// public override Func<IQArray<Qubit>, QVoid> __Body__ => (__in__) =>
|
||||
// {
|
||||
|
||||
// // (__T__ location, ICallable op, __U__ input, Int64 num_tests) = __in__;
|
||||
// // var filename = (location is QVoid) ? "" : location.ToString();
|
||||
// if (simulator != null)
|
||||
// {
|
||||
// (QCTraceSimulatorImpl)simulator.DoPrimitiveOperation((int)PrimitiveOperationsGroups.R, __in__,
|
||||
// 0, true);
|
||||
|
||||
|
||||
// // ((SparseSimulatorProcessor)simulator.QuantumProcessor).BenchmarkInit(filename, op.FullName);
|
||||
// // for (Int64 i = 0; i < num_tests; i++)
|
||||
// // {
|
||||
// // ((SparseSimulatorProcessor)simulator.QuantumProcessor).StartOp(op.FullName);
|
||||
// // op.Apply<__V__>(input);
|
||||
// // ((SparseSimulatorProcessor)simulator.QuantumProcessor).EndOp();
|
||||
// // }
|
||||
// // ((SparseSimulatorProcessor)simulator.QuantumProcessor).BenchmarkFinalize();
|
||||
// return QVoid.Instance;
|
||||
// }
|
||||
// else
|
||||
// { // If it's another type of simulator: do nothing
|
||||
|
||||
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Microsoft.Quantum.Canon {
|
||||
|
||||
open Microsoft.Quantum.Intrinsic;
|
||||
|
||||
|
||||
operation Touch (qubits: Qubit[]) : Unit {
|
||||
body intrinsic;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FileHelpers" Version="3.4.0" />
|
||||
<PackageReference Include="Microsoft.Quantum.Standard" Version="0.7.1905.3109" />
|
||||
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.7.1905.3109" />
|
||||
<PackageReference Include="Microsoft.Quantum.Standard" Version="0.24.208024" />
|
||||
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.24.208024" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
Загрузка…
Ссылка в новой задаче