Skip to content

Commit

Permalink
Restructured project to be more Pythonic
Browse files Browse the repository at this point in the history
  • Loading branch information
jvdsn committed Sep 17, 2021
1 parent 070549c commit 3c7d596
Show file tree
Hide file tree
Showing 21 changed files with 63 additions and 49 deletions.
36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
## Introduction
This repository contains the code for my master's thesis: "A White-Box Speck Implementation using Self-Equivalence Encodings". The code can roughly be divided in six parts:
* `src/code_generator/`: this directory contains all code related to output code generation, including the different code generation strategies.
* `src/self_equivalences/`: this directory contains all code related to the generation of (random) linear and affine self-equivalences, as well as combining these self-equivalences.
* `src/white_box_speck.py`: this file contains the `WhiteBoxSpeck` class, responsible for generating the encoded matrices and vectors when a Speck key is provided.
* `src/external_encodings.py`: this file contains code generate random linear and affine external encodings, and the code required to output these encodings.
* `src/main.py`: the main Python file, containing miscellaneous code related to argument handling, logging, and directing the other components.
* `src/attacks`: this directory is special. It contains proof-of-concept implementations of attacks to recover self-equivalence encodings and external encodings from a white-box Speck implementation.
This repository contains the code for my master's thesis: "A White-Box Speck Implementation using Self-Equivalence Encodings". The main code can roughly be divided in five parts:
* `white_box_speck/code_generator/`: this directory contains all code related to output code generation, including the different code generation strategies.
* `white_box_speck/self_equivalences/`: this directory contains all code related to the generation of (random) linear and affine self-equivalences, as well as combining these self-equivalences.
* `white_box_speck/__init__.py`: this file contains the `WhiteBoxSpeck` class, responsible for generating the encoded matrices and vectors when a Speck key is provided.
* `white_box_speck/__main__.py`: the main Python file, containing miscellaneous code related to argument handling, logging, and directing the other components.
* `white_box_speck/external_encodings.py`: this file contains code generate random linear and affine external encodings, and the code required to output these encodings.

Additionally, this repository also contains proof-of-concept implementations of attacks to recover self-equivalence encodings and external encodings from a white-box Speck implementation. These attacks can be found in the `attacks` directory.

## Requirements
This project uses Python 3 and the [SageMath](https://www.sagemath.org/) package.
Expand All @@ -15,11 +16,11 @@ The `test.sh` file included in this repository is a simple Bash script which tes

To generate white-box Speck encryption implementations manually, you will need to execute the `main.py` file:
```
sage -python src/main.py -h
sage -python -m white_box_speck -h
```
This will output the help dialogue with possible arguments, copied here for your convenience:
```
usage: main.py [-h] [--block-size [{32,48,64,96,128}]] [--key-size [{64,72,96,128,144,192,256}]] [--output-dir [OUTPUT_DIR]] [--self-equivalences [{affine,linear}]] [--debug] key [key ...]
usage: sage -python -m white_box_speck [-h] [--block-size [{32,48,64,96,128}]] [--key-size [{64,72,96,128,144,192,256}]] [--output-dir [OUTPUT_DIR]] [--self-equivalences [{affine,linear}]] [--debug] key [key ...]
Generate a white-box Speck implementation using self-equivalence encodings
Expand Down Expand Up @@ -65,20 +66,29 @@ In general, the bit-packed code generation strategy is the most efficient overal

Generating a white-box `Speck32/64` implementation using only linear self-equivalences (just for demonstration purposes, linear self-equivalences are very insecure):
```
sage -python src/main.py --block-size 32 --key-size 64 --self-equivalences linear 1918 1110 0908 0100
sage -python -m white_box_speck --block-size 32 --key-size 64 --self-equivalences linear 1918 1110 0908 0100
```

Generating a white-box `Speck64/128` implementation with debug logging enabled:
```
sage -python src/main.py --block-size 64 --key-size 128 --debug 1b1a1918 13121110 0b0a0908 03020100
sage -python -m white_box_speck --block-size 64 --key-size 128 --debug 1b1a1918 13121110 0b0a0908 03020100
```

Generating a white-box `Speck128/256` implementation in the `out` directory:

```
sage -python src/main.py --block-size 128 --key-size 256 --output-dir out 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100
sage -python -m white_box_speck --block-size 128 --key-size 256 --output-dir out 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100
```

## Attacks

As mentioned, `src/attacks` contains proof-of-concept implementations of attacks to recover self-equivalence encodings and external encodings from a white-box Speck implementation. The attacks can be tested using the `test_attacks.sh` script. This script will output the results of the attack (i.e. whether the master key and external encodings could be recovered), for each Speck parameter set.
As mentioned, the `attacks` directory contains proof-of-concept implementations of attacks to recover self-equivalence encodings and external encodings from a white-box Speck implementation. The attacks can be tested by running the Python scripts:
```
sage -python attacks/linear.py
```
or
```
sage -python attacks/anf.py
```

This will output the results of the attack (i.e. whether the master key and external encodings could be recovered), for each Speck parameter set.
File renamed without changes.
10 changes: 7 additions & 3 deletions src/attacks/anf.py → attacks/anf.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import logging
import os
import sys
from itertools import product
from random import randint

from sage.all import GF
from sage.all import vector
from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing

sys.path.insert(1, os.path.dirname(os.path.realpath(os.path.abspath(__file__))))

from attacks import inverse_key_schedule
from external_encodings import random_linear_external_encoding
from self_equivalences.anf import AffineSelfEquivalenceProvider
from self_equivalences.anf import LinearSelfEquivalenceProvider
from white_box_speck.external_encodings import random_linear_external_encoding
from white_box_speck.self_equivalences.anf import AffineSelfEquivalenceProvider
from white_box_speck.self_equivalences.anf import LinearSelfEquivalenceProvider
from white_box_speck import WhiteBoxSpeck

gf2 = GF(2)
Expand Down
8 changes: 6 additions & 2 deletions src/attacks/linear.py → attacks/linear.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import logging
import os
import sys
from random import randint

from sage.all import GF
from sage.all import vector

sys.path.insert(1, os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__)))))

from attacks import inverse_key_schedule
from external_encodings import random_linear_external_encoding
from self_equivalences.linear import LinearSelfEquivalenceProvider
from white_box_speck.external_encodings import random_linear_external_encoding
from white_box_speck.self_equivalences.linear import LinearSelfEquivalenceProvider
from white_box_speck import WhiteBoxSpeck

gf2 = GF(2)
Expand Down
2 changes: 1 addition & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ STRATEGIES=(
for ((i = 0; i < ${#BLOCK_SIZES[@]}; i++)); do
for self_equivalences in "${SELF_EQUIVALENCES[@]}"; do
echo "Testing Speck${BLOCK_SIZES[i]}/${KEY_SIZES[i]} with $self_equivalences self equivalences and key '${KEYS[i]}'"
sage -python src/main.py --block-size ${BLOCK_SIZES[i]} --key-size ${KEY_SIZES[i]} --self-equivalences $self_equivalences $DEBUG ${KEYS[i]}
sage -python -m white_box_speck --block-size ${BLOCK_SIZES[i]} --key-size ${KEY_SIZES[i]} --self-equivalences $self_equivalences $DEBUG ${KEYS[i]}

gcc -o inverse_input_external_encoding inverse_input_external_encoding.c
gcc -o inverse_output_external_encoding inverse_output_external_encoding.c
Expand Down
4 changes: 0 additions & 4 deletions test_attacks.sh

This file was deleted.

File renamed without changes.
30 changes: 15 additions & 15 deletions src/main.py → white_box_speck/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
from argparse import ArgumentParser
from pathlib import Path

from code_generator.bit_packed import BitPackedCodeGenerator
from code_generator.default import DefaultCodeGenerator
from code_generator.inlined import InlinedCodeGenerator
from code_generator.inlined_bit_packed import InlinedBitPackedCodeGenerator
from code_generator.simd import SIMDCodeGenerator
from code_generator.sparse_matrix import SparseMatrixCodeGenerator
from external_encodings import InputExternalEncodingCodeGenerator
from external_encodings import OutputExternalEncodingCodeGenerator
from external_encodings import random_affine_external_encoding
from external_encodings import random_linear_external_encoding
from self_equivalences.anf import AffineSelfEquivalenceProvider
from self_equivalences.anf import LinearSelfEquivalenceProvider
from white_box_speck import WhiteBoxSpeck

parser = ArgumentParser(description="Generate a white-box Speck implementation using self-equivalence encodings")
from . import WhiteBoxSpeck
from .code_generator.bit_packed import BitPackedCodeGenerator
from .code_generator.default import DefaultCodeGenerator
from .code_generator.inlined import InlinedCodeGenerator
from .code_generator.inlined_bit_packed import InlinedBitPackedCodeGenerator
from .code_generator.simd import SIMDCodeGenerator
from .code_generator.sparse_matrix import SparseMatrixCodeGenerator
from .external_encodings import InputExternalEncodingCodeGenerator
from .external_encodings import OutputExternalEncodingCodeGenerator
from .external_encodings import random_affine_external_encoding
from .external_encodings import random_linear_external_encoding
from .self_equivalences.anf import AffineSelfEquivalenceProvider
from .self_equivalences.anf import LinearSelfEquivalenceProvider

parser = ArgumentParser(prog="sage -python -m white_box_speck", description="Generate a white-box Speck implementation using self-equivalence encodings")
parser.add_argument("key", nargs="+", help="the key to use for the Speck implementation, a hexadecimal representation of the words")
parser.add_argument("--block-size", nargs="?", type=int, default=128, choices=[32, 48, 64, 96, 128], help="the block size in bits of the Speck implementation (default: %(default)i)")
parser.add_argument("--key-size", nargs="?", type=int, default=256, choices=[64, 72, 96, 128, 144, 192, 256], help="the key size in bits of the Speck implementation (default: %(default)i)")
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator import CodeGenerator
from . import CodeGenerator


class BitPackedCodeGenerator(CodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator import CodeGenerator
from . import CodeGenerator


class DefaultCodeGenerator(CodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator import CodeGenerator
from . import CodeGenerator


class InlinedCodeGenerator(CodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator.bit_packed import BitPackedCodeGenerator
from .bit_packed import BitPackedCodeGenerator


class InlinedBitPackedCodeGenerator(BitPackedCodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator.bit_packed import BitPackedCodeGenerator
from .bit_packed import BitPackedCodeGenerator


class SIMDCodeGenerator(BitPackedCodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from code_generator import CodeGenerator
from . import CodeGenerator


class SparseMatrixCodeGenerator(CodeGenerator):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from sage.all import random_vector
from sage.all import vector

from code_generator.bit_packed import BitPackedCodeGenerator
from .code_generator.bit_packed import BitPackedCodeGenerator

ring = GF(2)

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from sage.all import matrix
from sage.all import vector

from self_equivalences import CoefficientsSelfEquivalenceProvider
from . import CoefficientsSelfEquivalenceProvider


class AffineSelfEquivalenceProvider(CoefficientsSelfEquivalenceProvider):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from sage.all import vector
from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing

from self_equivalences import CoefficientsSelfEquivalenceProvider
from . import CoefficientsSelfEquivalenceProvider

gf2 = GF(2)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from sage.all import matrix
from sage.all import vector

from self_equivalences import SelfEquivalenceProvider
from . import SelfEquivalenceProvider


class CombinedSelfEquivalenceProvider(SelfEquivalenceProvider):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from sage.all import matrix
from sage.all import vector

from self_equivalences import CoefficientsSelfEquivalenceProvider
from . import CoefficientsSelfEquivalenceProvider


class LinearSelfEquivalenceProvider(CoefficientsSelfEquivalenceProvider):
Expand Down

0 comments on commit 3c7d596

Please sign in to comment.