// register x - initially loaded with x // register N - initially loaded with N // control - control bit // other registers - initially 0 // after computation register B changes and contains: [(a*x) mod N] // Insecure version: registers widths etc. are not checked public static void CMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { ulong power2 = 1; for (int i = 0; i < x.Width; i++, power2 *= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // adding [(2^i * a) + B] modulo N comp.AddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } // if control == 0 // then B register contains still 0 // so we copy X register into B register comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); }
// register x - initially loaded with x // register N - initially loaded with N // control - control bit // other registers - initially 0 // after computation register B changes and contains: [(a*x) mod N] // Insecure version: registers widths etc. are not checked public static void CMultModulo( this QuantumComputer comp, Register a, Register b, Register c, Register N, Register x, RegisterRef control, ulong valueA, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, c, N, x, control, valueA, valueN }; comp.AddParametricGate("CMultModulo", parameters); return; } else { comp.Group = true; } ulong power2 = 1; for (int i = 0; i < x.Width; i++, power2 *= 2) { // loading A register with (2^i * a) mod N ulong toLoad = (valueA * power2) % valueN; comp.LoadNumber(a, toLoad, control, x[i]); // adding [(2^i * a) + B] modulo N comp.AddModulo(a, b, c, N, valueN); // unloading [(2^i * a) mod N] from A register comp.LoadNumber(a, toLoad, control, x[i]); } // if control == 0 // then B register contains still 0 // so we copy X register into B register comp.SigmaX(control); for (int i = 0; i < x.Width; i++) { comp.Toffoli(b[i], control, x[i]); } comp.SigmaX(control); }
// register A - initially loaded with a // register B - initially loaded with b // after computation in register B: (a+b) mod N // using scratch registers inside // register B must be exactly one bit wider than A to store carry bit // Secure version: throws Exceptions if arguments are invalid public static void AddModulo( this QuantumComputer comp, Register a, Register b, ulong valueN) { Validate(a, b, valueN); Register c = comp.NewRegister(0, a.Width + 1); Register N = comp.NewRegister(valueN, a.Width); comp.AddModulo(a, b, c, N, valueN); comp.DeleteRegister(ref N); comp.DeleteRegister(ref c); }
// register A - initially loaded with a // register B - initially loaded with b // after computation in register B: (a+b) mod N // using scratch registers inside // register B must be exactly one bit wider than A to store carry bit // Secure version: throws Exceptions if arguments are invalid public static void AddModulo( this QuantumComputer comp, Register a, Register b, ulong valueN) { if (comp.Group) { object[] parameters = new object[] { comp, a, b, valueN }; comp.AddParametricGate("AddModulo", parameters); return; } else { comp.Group = true; } Validate(a, b, valueN); Register c = comp.NewRegister(0, a.Width + 1); Register N = comp.NewRegister(valueN, a.Width); comp.AddModulo(a, b, c, N, valueN); comp.DeleteRegister(ref N); comp.DeleteRegister(ref c); }