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

3cH0_Nu1L發表於2023-03-17

一、概述

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

二、演算法流程

  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)

相關文章