Spaces:
Sleeping
Sleeping
File size: 6,075 Bytes
0173bbf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
from .base import QuantumProtocol
from qiskit_aer import Aer
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
import numpy as np
import random
from typing import Dict, List, Tuple
from qiskit.visualization import circuit_drawer
class E91Protocol(QuantumProtocol):
"""
Implementação do protocolo E91 (Ekert91) baseado em emaranhamento.
O protocolo E91 usa pares de qubits emaranhados e medições em diferentes ângulos
para estabelecer uma chave segura e verificar a presença de espionagem através
da violação das desigualdades de Bell.
"""
def __init__(self, key_length: int = 128):
super().__init__(key_length)
self.simulator = Aer.get_backend('qasm_simulator')
self.current_circuit = None
# Ângulos de medição para Alice e Bob
self.alice_angles = [0, np.pi/4, np.pi/2]
self.bob_angles = [np.pi/4, np.pi/2, 3*np.pi/4]
def _prepare_entangled_pair(self) -> QuantumCircuit:
"""
Prepara um par de qubits emaranhados no estado de Bell Φ+.
Returns:
QuantumCircuit: Circuito com o par emaranhado
"""
qr = QuantumRegister(2, 'q')
cr = ClassicalRegister(2, 'c')
qc = QuantumCircuit(qr, cr)
# Criar estado de Bell Φ+ = (|00⟩ + |11⟩)/√2
qc.h(qr[0])
qc.cx(qr[0], qr[1])
self.current_circuit = qc
return qc
def _measure_qubit(self, circuit: QuantumCircuit, angle: float, qubit: int) -> QuantumCircuit:
"""
Adiciona medição em um ângulo específico para um qubit.
Args:
circuit (QuantumCircuit): Circuito a ser medido
angle (float): Ângulo de medição
qubit (int): Índice do qubit a ser medido
Returns:
QuantumCircuit: Circuito com medição adicionada
"""
# Rotação para o ângulo de medição
circuit.ry(2*angle, qubit)
circuit.measure([qubit], [qubit])
return circuit
def _check_bell_inequality(self, correlations: List[float]) -> bool:
"""
Verifica a violação da desigualdade de CHSH.
Args:
correlations (List[float]): Lista de correlações medidas
Returns:
bool: True se a desigualdade for violada (indicando ausência de espião)
"""
# Cálculo do parâmetro S da desigualdade CHSH
S = abs(sum(correlations))
# O valor teórico máximo é 2√2 ≈ 2.82
# Um valor > 2 indica violação da desigualdade
return S > 2
def _calculate_correlation(self, alice_results: List[int],
bob_results: List[int]) -> float:
"""
Calcula a correlação entre as medições de Alice e Bob.
Args:
alice_results (List[int]): Resultados das medições de Alice
bob_results (List[int]): Resultados das medições de Bob
Returns:
float: Valor da correlação (-1 a 1)
"""
if not alice_results or not bob_results:
return 0
return np.mean([a == b for a, b in zip(alice_results, bob_results)])
def generate_key(self) -> Dict[str, List[int]]:
"""
Executa o protocolo E91 completo para gerar uma chave compartilhada.
Returns:
Dict[str, List[int]]: Dicionário contendo as chaves finais de Alice e Bob
"""
self.logger.info(f"Iniciando protocolo E91 para gerar chave de {self.key_length} bits")
alice_key = []
bob_key = []
correlations = []
# Precisamos de mais pares para compensar descartes
num_pairs = self.key_length * 4
for _ in range(num_pairs):
# Preparar par emaranhado
circuit = self._prepare_entangled_pair()
# Alice e Bob escolhem ângulos aleatoriamente
alice_angle = random.choice(self.alice_angles)
bob_angle = random.choice(self.bob_angles)
# Adicionar medições
circuit = self._measure_qubit(circuit, alice_angle, 0) # Alice
circuit = self._measure_qubit(circuit, bob_angle, 1) # Bob
# Executar circuito
job = self.simulator.run(circuit, shots=1)
result = job.result()
counts = list(result.get_counts().keys())[0]
alice_result = int(counts[0])
bob_result = int(counts[1])
# Verificar se os ângulos são compatíveis para a chave
if alice_angle == bob_angle:
alice_key.append(alice_result)
bob_key.append(bob_result)
else:
# Usar para teste de Bell
correlation = self._calculate_correlation([alice_result], [bob_result])
correlations.append(correlation)
# Verificar violação da desigualdade de Bell
if not self._check_bell_inequality(correlations):
self.logger.error("Possível espionagem detectada - violação de Bell não observada!")
return {"alice": [], "bob": []}
# Cortar para o tamanho desejado
alice_key = alice_key[:self.key_length]
bob_key = bob_key[:self.key_length]
self.logger.info(f"Protocolo E91 concluído com sucesso. "
f"Chave final de {len(alice_key)} bits gerada.")
return {
"alice": alice_key,
"bob": bob_key
}
def get_circuit_visualization(self) -> str:
"""
Retorna a visualização do circuito atual em ASCII.
Returns:
str: Representação ASCII do circuito
"""
if self.current_circuit:
return circuit_drawer(self.current_circuit, output='text')
return "Nenhum circuito disponível" |