CSE442T Introduction to Cryptography (Lecture 22)
Chapter 7: Composability
So far we’ve sought security against
Adversary knows , but nothing else.
Attack models
Known plaintext attack (KPA)
Adversary has seen .
are known to the adversary.
Given new , is previous knowledge helpful?
Chosen plaintext attack (CPA)
Adversary can choose and obtain .
Then adversary see new encryption . with the same key.
Example:
In WWII, Japan planned to attack “AF”, but US suspected it means Midway.
So US use Axis: and ran out of supplies.
Then US know Japan will attack Midway.
Chosen ciphertext attack (CCA)
Adversary can choose and obtain .
Definition 168.1 (Secure private key encryption against attacks)
Capture these ideas with the adversary having oracle access.
Let be a private key encryption scheme. Let a random variable where is an n.u.p.p.t. The security parameter is , denoting the real scheme or the adversary’s challenge.
The experiment is the following:
- Key
- Adversary queries oracle
- queries oracle to distinguish is encryption of or
- outputs bit which is either zero or one
is CPA/CCA1/CCA2 secure if for all PPT adversaries ,
where is statistical indistinguishability.
| Security | ||
|---|---|---|
| CPA | ||
| CCA1 | ||
| CCA2 (or full CCA) |
Note that will not allowed to query decryption of a functioning ciphertext.
You can imagine the experiment is a class as follows:
n = 1024
@lru_cache(None)
def oracle_1(m,key,**kwargs):
"""
Query oracle 1
"""
pass
@lru_cache(None)
def oracle_2(c,key,**kwargs):
"""
Query oracle 2
"""
pass
class Experiment:
def __init__(self, key, oracle_1, oracle_2):
self.key = key
self.oracle_1 = oracle_1
self.oracle_2 = oracle_2
def sufficient_trial(self):
pass
def generate_test_message(self):
pass
def set_challenge(self, c):
self.challenge = c
def query_1(self):
while not self.sufficient_trial():
self.oracle_1(m,self.key,**kwargs)
def challenge(self):
"""
Return m_0, m_1 for challenge
"""
m_0, m_1 = self.generate_test_message()
self.m_0 = m_0
self.m_1 = m_1
return m_0, m_1
def query_2(self, c):
while not self.sufficient_trial():
self.oracle_2(c,self.key,**kwargs)
def output(self):
return 0 if self.challenge==m_0 else 1
if __name__ == "__main__":
key = random.randint(0, 2**n)
exp = Experiment(key, oracle_1, oracle_2)
exp.query_1()
m_0, m_1 = exp.challenge()
choice = random.choice([m_0, m_1])
exp.set_challenge(choice)
exp.query_2()
b_prime = exp.output()
print(f"b'={b_prime}, b={choice==m_0}")Theorem: Our mms private key encryption scheme is CPA, CCA1 secure.
Have a PRF family
outputs and samples from the PRF family.
samples and outputs . For multi-message security, we need to encrypt at once.
outputs .
Familiar Theme:
- Show the R.F. version is secure.
- If the PRF version were insecure, then the PRF can be distinguished from a random function…
- queries
- queries , where
- ,
- Query round similar to above.
As long as was never seen in querying rounds, .
(by the total number of queries in all rounds.)
This encryption scheme is not CCA2 secure.
After round 1, ,
in round 2.
Query .
Encrypt then authenticate
Have a PRF family
outputs and samples from the PRF family.
samples and let and . Then we output . where is the encryption, and is the tag. For multi-message security, we need to encrypt at once.
checks if . If so, output . Otherwise, output .
Show that this scheme is CPA secure.
- Show that the modifier version where is replaced with a random function is CCA2 secure.
- If ours isn’t, then PRF detector can be created.
Suppose is not secure, then which can distinguish with non-negligible probability. We will use this to construct which breaks the CPA security of .
Let be the PPT algorithm that on input , does the following:
- Run
- Let be the messages that asked for in the second round.
- Choose uniformly at random.
- Query to the oracle.
- Let be the challenge ciphertext.
- Return whatever outputs.