differential bias black box + small fix
This commit is contained in:
@@ -15,6 +15,15 @@ pip install pytest
|
|||||||
pytest
|
pytest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## run linear and differential bias empirical tests
|
||||||
|
|
||||||
|
in the venv
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tea3-linear-bias
|
||||||
|
tea3-differential-bias
|
||||||
|
```
|
||||||
|
|
||||||
## run sagemath script
|
## run sagemath script
|
||||||
|
|
||||||
`deactivate` the venv first, then with sagemath installed:
|
`deactivate` the venv first, then with sagemath installed:
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ testpaths = ["tests"]
|
|||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
tea3-linear-bias = "tea3.tea3linearbias:main"
|
tea3-linear-bias = "tea3.tea3linearbias:main"
|
||||||
|
tea3-differential-bias = "tea3.tea3differentialbias:main"
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from random import Random
|
||||||
|
|
||||||
|
from .tea3 import Tea3
|
||||||
|
|
||||||
|
|
||||||
|
def rand_key(rng: Random) -> list[int]:
|
||||||
|
return [rng.getrandbits(8) for _ in range(10)]
|
||||||
|
|
||||||
|
|
||||||
|
def xor_key_with_delta(key: list[int], delta: bytes | list[int], offset: int = 0) -> list[int]:
|
||||||
|
"""
|
||||||
|
XOR a delta into a key starting at offset.
|
||||||
|
"""
|
||||||
|
out = list(key)
|
||||||
|
for i, d in enumerate(delta):
|
||||||
|
j = offset + i
|
||||||
|
if j >= len(out):
|
||||||
|
break
|
||||||
|
out[j] ^= d & 0xFF
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DiffBiasResult:
|
||||||
|
samples: int
|
||||||
|
matches: int
|
||||||
|
p_match: float
|
||||||
|
bias: float
|
||||||
|
estimated_needed_samples: float
|
||||||
|
|
||||||
|
|
||||||
|
def estimate_black_box_differential_bias(
|
||||||
|
*,
|
||||||
|
frame_number: int,
|
||||||
|
key_delta: bytes | list[int],
|
||||||
|
key_delta_offset: int = 0,
|
||||||
|
output_byte_index: int = 0,
|
||||||
|
target_diff: int = 0x00,
|
||||||
|
samples: int = 10000,
|
||||||
|
seed: int = 1,
|
||||||
|
) -> DiffBiasResult:
|
||||||
|
rng = Random(seed)
|
||||||
|
matches = 0
|
||||||
|
target_diff &= 0xFF
|
||||||
|
|
||||||
|
for _ in range(samples):
|
||||||
|
key1 = rand_key(rng)
|
||||||
|
key2 = xor_key_with_delta(key1, key_delta, key_delta_offset)
|
||||||
|
|
||||||
|
tea1 = Tea3(frame_number, key1)
|
||||||
|
tea2 = Tea3(frame_number, key2)
|
||||||
|
|
||||||
|
out1 = 0
|
||||||
|
out2 = 0
|
||||||
|
for _ in range(output_byte_index + 1):
|
||||||
|
out1 = tea1.next_byte()
|
||||||
|
out2 = tea2.next_byte()
|
||||||
|
|
||||||
|
diff = (out1 ^ out2) & 0xFF
|
||||||
|
if diff == target_diff:
|
||||||
|
matches += 1
|
||||||
|
|
||||||
|
p_match = matches / samples
|
||||||
|
random_baseline = 1.0 / 256.0
|
||||||
|
bias = abs(p_match - random_baseline)
|
||||||
|
|
||||||
|
needed = float("inf") if bias == 0 else 1.0 / (bias * bias)
|
||||||
|
|
||||||
|
return DiffBiasResult(
|
||||||
|
samples=samples,
|
||||||
|
matches=matches,
|
||||||
|
p_match=p_match,
|
||||||
|
bias=bias,
|
||||||
|
estimated_needed_samples=needed,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
frame = 0x12345678
|
||||||
|
|
||||||
|
key_delta = [0x01]
|
||||||
|
|
||||||
|
res = estimate_black_box_differential_bias(
|
||||||
|
frame_number=frame,
|
||||||
|
key_delta=key_delta,
|
||||||
|
key_delta_offset=0,
|
||||||
|
output_byte_index=0,
|
||||||
|
target_diff=0x00,
|
||||||
|
samples=20000,
|
||||||
|
seed=123,
|
||||||
|
)
|
||||||
|
print("black-box differential bias")
|
||||||
|
print("expected non-biased p_match: 1/256 = 0.00390625") # 256 possibilities for 1 Byte
|
||||||
|
print(res)
|
||||||
@@ -63,4 +63,5 @@ def main():
|
|||||||
seed=123,
|
seed=123,
|
||||||
)
|
)
|
||||||
print("black-box output bias")
|
print("black-box output bias")
|
||||||
|
print("expected non-biased p_match: 1/2") # 2 possibilities for 1 bit
|
||||||
print(res)
|
print(res)
|
||||||
|
|||||||
Reference in New Issue
Block a user