基於量子隨機遊走的影象加密演演算法

2023-03-17 18:00:26

一、概述

  量子隨機遊走是一種基於量子力學的隨機遊走模型,其具有良好的隨機性和不可預測性,因此被廣泛應用於密碼學中。基於量子隨機遊走的影象加密演演算法是一種新興的加密演演算法,其基本思路是將明文影象轉換為量子態,通過量子隨機遊走對量子態進行加密,最後將加密後的量子態轉換為密文影象。

二、演演算法流程

  1. 將明文影象轉換為量子態:首先將明文影象轉換為二進位制編碼,然後將編碼轉換為對應的量子態。這可以通過一些常見的量子態製備方法來實現,例如 Hadamard 變換、相位旋轉門等。

  2. 進行量子隨機遊走加密:將生成的量子態輸入到哈密頓量中進行量子隨機遊走,以實現加密。其中哈密頓量的構造和具體實現方法可能有多種選擇,例如可以利用 Grover 演演算法來進行哈密頓量的構造。

  3. 將加密後的量子態轉換為密文影象:將加密後的量子態進行測量,然後將測量結果轉換為對應的二進位制編碼,最後將編碼還原為密文影象。

  需要注意的是,量子隨機遊走過程的成功與否取決於構造的哈密頓量,而構造哈密頓量是該演演算法的關鍵。此外,加密和解密過程中需要保證金鑰的安全性,否則會導致演演算法失效。

  該演演算法具有很強的隨機性和不可預測性,能夠有效保護影象的安全性和隱私性。同時,由於量子隨機遊走具有高效的性質,因此該演演算法的加密效率也較高。但需要注意的是,該演演算法還處於研究階段,其安全性和可靠性有待進一步驗證和完善。

三、演演算法實現

  1. 影象畫素置換的實現方式:可以通過使用置換矩陣的方式實現畫素置換,也可以通過使用置換函數的方式實現畫素置換。其中,置換矩陣可以通過隨機生成一個置換矩陣來實現,置換函數可以通過使用一個隨機的函數來實現。

  2. 影象畫素值的量子態轉換:需要將影象畫素值轉換成量子態。可以使用qiskit中的qubit來表示量子態,將影象畫素值轉換成qubit,然後通過量子門的操作,實現畫素值的量子態轉換。

  3. 量子隨機遊走的實現方式:可以通過使用量子隨機遊走的概率轉移矩陣來實現,也可以通過使用量子隨機遊走的電路來實現。其中,概率轉移矩陣可以通過隨機生成一個概率轉移矩陣來實現,量子隨機遊走的電路可以通過qiskit中的量子門和量子電路實現。

  4. 加密解密的實現方式:基於量子隨機遊走的影象加密演演算法可以通過對影象畫素值進行加密,然後通過相反的過程對影象畫素值進行解密。在實現過程中,需要注意加密和解密的過程是相反的,即解密過程需要使用加密過程中使用的引數和金鑰。

  5. 演演算法的效能和安全性:需要考慮演演算法的效能和安全性。演演算法的效能可以通過對加密和解密的時間和空間複雜度進行分析來評估。演演算法的安全性可以通過對演演算法的加密強度進行分析來評估,例如,對演演算法的置換矩陣和概率轉移矩陣進行分析,以及對演演算法的安全性進行模擬和實驗驗證。

四、部分功能程式碼實現

1.置換矩陣

  假設需要對一個n×n的影象進行畫素置換,可以隨機生成一個n×n的置換矩陣P來實現畫素置換。置換矩陣P中的每一個元素都是0或1,且每一行和每一列都有且僅有一個元素為1,其餘元素都為0。在畫素置換的過程中,可以將原始影象的每一個畫素的位置與置換矩陣P中對應的位置進行置換,從而實現畫素的混淆。

MATLAB

function P = generate_permutation_matrix(n)
% 生成一個n×n的置換矩陣,用於影象畫素置換

P = zeros(n);
for i = 1:n
    row_idx = randperm(n, 1);
    P(i, row_idx) = 1;
end

end

該函數使用MATLAB內建函數randperm生成一個n×1的隨機排列向量row_idx,並將其賦值給置換矩陣P中的第i行中的第row_idx個元素。最後,將生成的置換矩陣P返回。

該函數可以通過輸入置換矩陣的維度n來生成一個n×n的置換矩陣。例如,通過執行以下程式碼可以生成一個10×10的置換矩陣P:

P = generate_permutation_matrix(10);

Python

import numpy as np

def generate_permutation_matrix(n):
    """
    生成一個n×n的置換矩陣,用於影象畫素置換

    Args:
        n: int, 置換矩陣的維度

    Returns:
        P: np.ndarray, n×n的置換矩陣
    """
    P = np.zeros((n, n), dtype=int)
    for i in range(n):
        row_idx = np.random.choice(n, size=1, replace=False)
        P[i][row_idx] = 1
    return P

該函數使用numpy庫生成一個n×n的全0矩陣P,並隨機生成每一行中的一個元素為1,從而生成置換矩陣P。最後,將生成的置換矩陣P返回。

2.置換函數

  在基於量子隨機遊走的影象加密演演算法中,需要使用置換函數對加密後的影象進行進一步混淆。置換函數可以將影象的每一個畫素位置進行置換,從而增加破解的難度。

MATLAB

function permuted_image = permutation(image, P)
% 對影象進行畫素置換

[n, ~] = size(image);
permuted_image = zeros(n);

for i = 1:n
    for j = 1:n
        new_i = find(P(:, i));
        new_j = find(P(:, j));
        permuted_image(new_i, new_j) = image(i, j);
    end
end

end

  該函數接受兩個輸入引數:待置換的影象和置換矩陣P。在函數內部,通過find函數查詢P矩陣中值為1的元素所在的行和列,然後根據這些行和列將原始影象中的畫素進行置換。最後,將置換後的影象返回。

  需要注意的是,該函數實現的置換是對灰度影象進行的,對於彩色影象,需要對每個顏色通道分別進行置換。

Python

import numpy as np

def permutation(image, P):
    """
    對影象進行畫素置換

    Args:
        image: np.ndarray, 待置換的影象
        P: np.ndarray, 置換矩陣

    Returns:
        permuted_image: np.ndarray, 置換後的影象
    """
    n = image.shape[0]
    permuted_image = np.zeros_like(image)
    for i in range(n):
        for j in range(n):
            new_i, new_j = np.where(P == 1)[1][i], np.where(P == 1)[1][j]
            permuted_image[new_i, new_j] = image[i, j]
    return permuted_image

  該函數接受兩個輸入引數:待置換的影象和置換矩陣P。在函數內部,使用np.where函數查詢P矩陣中值為1的元素所在的位置,並根據這些位置將原始影象中的畫素進行置換。最後,將置換後的影象返回。

  需要注意的是,該函數實現的置換是對灰度影象進行的,對於彩色影象,需要對每個顏色通道分別進行置換。

3.影象畫素值轉換成量子態

 在量子影象加密演演算法中,需要將影象的畫素值轉換成對應的量子態,以便進行後續的量子操作。這個過程可以通過將每個畫素值表示為二進位制數,然後將每一位作為一個量子位元,轉換成對應的量子態

MATLAB

function qc = pixel_to_quantum(image)
% 將影象的畫素值轉換成量子態

n = size(image, 1);
q = qubit(n);
qc = quantumCircuit(q);

for i = 1:n
    for j = 1:n
        % 將畫素值表示為二進位制數
        binary = dec2bin(image(i, j), 8) - '0';
        % 將每一位作為一個量子位元,轉換成對應的量子態
        for k = 1:length(binary)
            if binary(k) == 1
                qc.x(q(k));
            end
        end
        qc.barrier();
    end
end

end

  在MATLAB中,可以使用Quantum Computing Toolbox來實現將影象畫素值轉換成量子態。

  該函數接受一個輸入引數:待轉換的影象。在函數內部,首先獲取影象的大小n,然後建立一個包含n個量子位元的量子電路物件。接下來,對於每一個畫素值,將其表示為8位元二進位制數,並將每一位作為一個量子位元,通過在量子電路中新增X門將其轉換成對應的量子態。最後,將量子電路物件返回。

  需要注意的是,該範例程式碼中假設影象是8位元灰度影象,對於其他位數的灰度影象或彩色影象,需要相應地進行修改。另外,在轉換過程中,也可以對畫素值進行量子編碼,以便在加密過程中加強影象的保密性。

Python

import numpy as np
from qiskit import QuantumCircuit, QuantumRegister

def pixel_to_quantum(image):
    """
    將影象的畫素值轉換成量子態

    Args:
        image: np.ndarray, 待轉換的影象

    Returns:
        qc: QuantumCircuit, 量子電路物件
    """
    n = image.shape[0]
    qc = QuantumCircuit(n, name='PixelToQuantum')
    for i in range(n):
        for j in range(n):
            # 將畫素值表示為二進位制數
            binary = bin(image[i, j])[2:].zfill(8)
            # 將每一位作為一個量子位元,轉換成對應的量子態
            for k, bit in enumerate(binary):
                if bit == '1':
                    qc.x(k)
            qc.barrier()
    return qc

  在量子影象加密演演算法中,需要將影象的畫素值轉換成對應的量子態,以便進行後續的量子操作。這個過程可以通過將每個畫素值表示為二進位制數,然後將每一位作為一個量子位元,轉換成對應的量子態。

  該函數接受一個輸入引數:待轉換的影象。在函數內部,首先獲取影象的大小n,然後建立一個包含n個量子位元的量子電路物件。接下來,對於每一個畫素值,將其表示為8位元二進位制數,並將每一位作為一個量子位元,通過在量子電路中新增X門將其轉換成對應的量子態。最後,將量子電路物件返回。

  需要注意的是,該範例程式碼中假設影象是8位元灰度影象,對於其他位數的灰度影象或彩色影象,需要相應地進行修改。另外,在轉換過程中,也可以對畫素值進行量子編碼,以便在加密過程中加強影象的保密性。

4.量子隨機遊走的程式碼實現

  量子隨機遊走是一個重要的量子演演算法,可以用於影象加密中的置換操作。在MATLAB中,可以使用Quantum Computing Toolbox來實現量子隨機遊走。

function qc = quantum_random_walk(n)
% 量子隨機遊走

q = qubit(n);
qc = quantumCircuit(q);

% 初始化量子位元為均勻疊加態
for i = 1:n
    qc.h(q(i));
end
qc.barrier();

% 定義角度和目標狀態
angle = pi / 4;
target = zeros(1, n);
target(1) = 1;

% 執行量子隨機遊走
for i = 1:n
    % 應用哈達瑪門
    qc.h(q(i));
    qc.barrier();
    % 應用相位門
    for j = 1:n
        if j == i
            continue;
        end
        qc.cphase(angle, q(j), q(i));
    end
    qc.barrier();
    % 應用反射門
    qc.mct(q(1:n-1), q(n), [], 'inverse');
    qc.barrier();
end

% 應用逆哈達瑪門
for i = 1:n
    qc.h(q(i));
end
qc.barrier();

end

  該函數接受一個輸入引數n,表示量子位元的數量。在函數內部,首先建立一個包含n個量子位元的量子電路物件,並將所有量子位元初始化為均勻疊加態。接下來,定義角度和目標狀態,並按照量子隨機遊走演演算法的步驟依次應用哈達瑪門、相位門、反射門和逆哈達瑪門。最後,將量子電路物件返回。

  需要注意的是,該範例程式碼中僅實現了一次量子隨機遊走,而在實際應用中通常需要多次執行量子隨機遊走以增強影象的置換效果。此外,量子隨機遊走的引數設定對於影象加密的效果也有重要影響,需要根據具體情況進行調整。

5.使用量子隨機遊走的概率轉移矩陣來實現量子隨機遊走

  在影象加密中,可以使用量子隨機遊走的概率轉移矩陣來實現置換操作。假設有n個畫素點,可以將每個畫素點表示為一個n維的列向量,其中每個維度表示畫素點的取值。量子隨機遊走的概率轉移矩陣可以定義為:

  P = (1/2n) * (I - D),

  其中I是n維的單位矩陣,D是度數矩陣,定義為:

  D(i, i) = sum(P(i, j)) (i = 1, 2, ..., n)

  可以使用MATLAB來實現量子隨機遊走的概率轉移矩陣,程式碼如下:

function [P, D] = quantum_random_walk_matrix(n)
% 量子隨機遊走的概率轉移矩陣

% 初始化單位矩陣和度數矩陣
I = eye(n);
D = zeros(n);

% 計算度數矩陣
for i = 1:n
    for j = 1:n
        if i == j
            continue;
        end
        D(i, i) = D(i, i) + 1/norm(i-j, 2);
    end
end

% 計算概率轉移矩陣
P = (1/2/n) * (I - D);

end

  該函數接受一個輸入引數n,表示畫素點的數量。在函數內部,首先初始化單位矩陣和度數矩陣,並計算度數矩陣的每個元素。接下來,按照概率轉移矩陣的定義計算概率轉移矩陣P,並將度數矩陣D和概率轉移矩陣P作為輸出返回。

  需要注意的是,在實際應用中,量子隨機遊走的概率轉移矩陣需要與影象進行對應,即將畫素點的n維列向量按照概率轉移矩陣進行置換。此外,量子隨機遊走的概率轉移矩陣的引數設定也對影象加密的效果有重要影響,需要根據具體情況進行調整。

6.使用qiskit中的量子門和量子電路實現量子隨機遊走

  在qiskit中,可以通過使用qiskit.quantum_info庫中的量子門和量子電路來實現量子隨機遊走。

範例程式碼

首先,需要匯入必要的庫和模組:

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
 from qiskit.quantum_info import Operator

然後,需要構造一個初始的量子電路,其中包含每個畫素值對應的量子位元。假設我們要處理的是一個4位元的影象,那麼可以這樣構造電路:

qr = QuantumRegister(4, 'q')
 cr = ClassicalRegister(4, 'c')
 circuit = QuantumCircuit(qr, cr)
接下來,需要將每個畫素值轉換為一個複數,並將其作為量子位元的初始態。可以使用qiskit.quantum_info.Statevector.from_label()函數來實現這一步驟:

import numpy as np

# 假設畫素值為[1, 2, 3, 4]
initial_state = np.array([1, 2, 3, 4]) / np.sqrt(np.sum(np.square([1, 2, 3, 4])))
circuit.initialize(initial_state, [qr[0], qr[1], qr[2], qr[3]])

接下來,需要構造量子隨機遊走的概率轉移矩陣。可以使用qiskit.quantum_info.Operator.from_label()函數來實現這一步驟。例如,可以使用Grover的搜尋演演算法來構造一個概率轉移矩陣:

# 構造一個包含兩個目標狀態的搜尋演演算法
grover_op = Operator.from_label('10')
diffusion_op = Operator.from_label('H' * 4) * Operator.from_label('X' * 4) * Operator.from_label('H' * 4) * Operator.from_label('Z' * 4) * Operator.from_label('H' * 4)
grover_op = diffusion_op * grover_op * diffusion_op

# 將概率轉移矩陣作為一個量子門新增到電路中
circuit.append(grover_op, [qr[0], qr[1], qr[2], qr[3]])

最後,可以測量電路的輸出結果,並將結果轉換為畫素值。可以使用qiskit的simulator模組來類比電路的輸出結果,例如:

from qiskit import Aer, execute

simulator = Aer.get_backend('qasm_simulator')
result = execute(circuit, simulator).result()
counts = result.get_counts(circuit)

# 將測量結果轉換為畫素值
pixel_values = []
for key in counts.keys():
    pixel_value = int(key, 2)
    pixel_values.append(pixel_value)

 這樣就可以實現量子隨機遊走,並將量子態轉換為畫素值。

通過 qiskit 框架來實現量子隨機遊走的電路

匯入必要的包和模組:

from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.circuit.library import QFT
from qiskit.quantum_info.operators import Operator
import numpy as np
定義量子暫存器和量子電路:

# 定義量子暫存器
qr = QuantumRegister(n, name='q')

# 定義經典暫存器
cr = ClassicalRegister(n, name='c')

# 定義量子電路
qc = QuantumCircuit(qr, cr, name='qrw')

其中,n 表示量子位元數。接著,我們需要定義概率轉移矩陣和其對應的量子門: 

# 定義概率轉移矩陣
p = np.zeros((2 ** n, 2 ** n))
for i in range(2 ** n):
    for j in range(2 ** n):
        if i == j:
            p[i][j] = 1 / (2 ** n)
        else:
            p[i][j] = (1 - gamma) / (2 ** n - 1)
    p[i] = p[i] / np.linalg.norm(p[i])

# 將概率轉移矩陣轉換為量子門
p_gate = Operator(p)

 其中,gamma 表示隨機遊走引數。接下來,我們需要將概率轉移矩陣作用於量子電路上:

qc.unitary(p_gate, qr)
然後,我們需要新增逆量子傅立葉變換和測量操作:

qc.append(QFT(n, do_swaps=False).inverse(), qr)
 qc.measure(qr, cr)
最後,我們可以通過 qiskit 提供的模擬器進行模擬和測試:

from qiskit import Aer, execute

backend = Aer.get_backend('qasm_simulator')
job = execute(qc, backend, shots=1024)
result = job.result()
counts = result.get_counts(qc)
print(counts)