Files
pydarc/docs/spn_algebra_template.md

279 lines
5.9 KiB
Markdown

# Permutation Algebra
This notebook is a prerequisite to following the DARC tutorial
## Key Generation Parameters
- block size: The number of characters we encode in a block. Block size isn't using in this notebook
- key height: The alphabet length. If we want to encode bytes, our alphabet length is 256.
If we want to encode lowercase letters a-z our alphabet length is 26. NKodes {{ height }} key {{ width }} attribute alphabet is {{ total_attr }}.
- key width: The number of bytes an encrypted charter is in our alphabet.
```
height = {{ height }}
width = {{ width }}
```
## Operand Types
### Inner Permutation Key
An inner permutation key (inner key for short) is a list of `height` rows, each a random permutation of an identity array of length `width`.
```
i0 = InnerKey.init_matrix(width, height)
i1 = InnerKey.init_matrix(width, height)
i2 = InnerKey.init_matrix(width, height)
i_identity = InnerKey.init_identity_matrix(width, height)
i0.matrix:
{% for row in i0.matrix -%}
{{ row }}
{% endfor %}
i1.matrix:
{% for row in i1.matrix -%}
{{ row }}
{% endfor %}
i2.matrix:
{% for row in i2.matrix -%}
{{ row }}
{% endfor %}
i_identity.matrix:
{% for row in i_identity.matrix -%}
{{ row }}
{% endfor %}
```
### Outer Permutation Key
An outer key is a list of `height` columns, each a random permutation of an identity array of length `height`.
It is used to permute the rows of inner, substitution and outer keys.
```
o0 = OuterKey.init_matrix(height)
o1 = OuterKey.init_matrix(height)
o2 = OuterKey.init_matrix(height)
o_identity = OuterKey.init_identity_matrix(height)
o0.matrix:
{{ o0.matrix }}
o1.matrix:
{{ o1.matrix }}
o2.matrix:
{{ o2.matrix }}
o_identity.matrix:
{{ o_identity.matrix }}
```
### Substitution Key
Substitution key is a matrix of `height` rows and `width` columns. Each row is a list of randomly generated bytes.
```
s0 = SubstitutionKey.init_matrix(width, height)
s1 = SubstitutionKey.init_matrix(width, height)
s2 = SubstitutionKey.init_matrix(width, height)
s_identity = SubstitutionKey.init_identity_matrix(width, height)
s0.matrix:
{% for row in s0.matrix -%}
{{ row }}
{% endfor %}
s1.matrix:
{% for row in s1.matrix -%}
{{ row }}
{% endfor %}
s2.matrix:
{% for row in s2.matrix -%}
{{ row }}
{% endfor %}
s_identity.matrix:
{% for row in s_identity.matrix -%}
{{ row }}
{% endfor %}
```
## Operators Types
### < Outer Permutation
#### Substitution Key < Outer Key
```
s0_o0 = s0 < o0
```
| idx |s0|s0| s0_o0 |
|-----|-|-|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ s0.matrix[idx] }}|{{ o0.matrix[0][idx] }}|{{ s0_o0.matrix[idx] }}|
{% endfor %}
#### Inner Key < Outer Key
i0_o0 = i0 < o0
| idx | i0 | o0 | i0_o0 |
|-----|----|----|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ i0.matrix[idx] }}|{{ o0.matrix[0][idx] }}|{{ i0_o0.matrix[idx] }}|
{% endfor %}
### << Inner Permutation
#### Outer Key << Outer Key
o0_o1 = o0 << o1
| idx | o0 | o1 | o0_o1 |
|-----|----|----|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ o0.matrix[0][idx] }}|{{ o1.matrix[0][idx] }}|{{ o0_o1.matrix[0][idx] }}|
{% endfor %}
#### Inner Key << Inner Key
i0_i1 = i0 << i1
| idx | i0 | i1 | i0_i1 |
|-----|----------------------------------------------------------|----|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ i0.matrix[idx] }}|{{ i1.matrix[idx] }}|{{ i0_i1.matrix[idx] }}|
{% endfor %}
#### Substitution Key << Inner Key
s0_i0 = s0 << i0
| idx | s0 | i0 | s0_i0 |
|-----|----|----|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ s0.matrix[idx] }}|{{ i0.matrix[idx] }}|{{ s0_i0.matrix[idx] }}|
{% endfor %}
### ~Permutation Inversion
#### ~Outer Key
inv_o0 = ~o0
| idx | o0 | ~o0 |
|-----|----|-----|
{% for idx in range(height) -%}
|{{idx}}|{{ o0.matrix[0][idx] }}|{{ inv_o0.matrix[0][idx] }}|
{% endfor %}
#### ~Inner Key
inv_i0 = ~i0
| idx | i0 | ~i0 |
|-----|----|-----|
{% for idx in range(height) -%}
|{{idx}}|{{ i0.matrix[idx] }}|{{ inv_i0.matrix[idx] }}|
{% endfor %}
### ^ Substitution
#### Substitution Key ^ Substitution Key
s0_s1 = s0 ^ s1
| idx | s0 | s1 | s0_s1 |
|-----|----|----|-------|
{% for idx in range(height) -%}
|{{idx}}|{{ s0.matrix[idx] }}|{{ s1.matrix[idx] }}|{{ s0_s1.matrix[idx] }}|
{% endfor %}
## Substitution Permutation Algebra
#### properites:
- associative: (a + b) + c = a + (b + c)
- commutative: a + b = b + a
- identity: a + 0 = a or a * 1 = a
- inverse: a + (-a) = 0 or a * 1/a = 1 (for all a ~= 0)
- distributive: a(b + c) = ab + ac
### Associative
#### Outer Key
```
(o0 << o1 << o2) == ((o0 << o1) << o2) == (o0 << (o1 << o2))
```
#### Inner Key
```
(i0 << i1 << i2) == ((i0 << i1) << i2) == (i0 << (i1 << i2))
```
#### Substitution Key
```
(s0 ^ s1 ^ s2) == ((s0 ^ s1) ^ s2) == (s0 ^ (s1 ^ s2))
```
### Commutative Property
Substitution is the only key type that is commutative
#### Substitution Key
```
(s0 ^ s1) == (s1 ^ s0)
```
### Identity Property
#### Outer Key
```
(o0 << o_identity) == o0
```
#### Inner Key
```
(i0 << i_identity) == i0
```
#### Substitution Key
```
(s0 ^ s_identity) == s0
```
### Inverse Property
#### Outer Key
```
(o0 << ~o0) == o_identity
```
#### Inner Key
```
(i0 << ~i0) == i_identity
```
#### Substitution Key
```
(s0 ^ s0) == s_identity
```
### Distributive
#### Inner Key/Outer Key
```
((i0 << i1) < o0) == ((i0 < o0) << (i1 < o0))
```
#### Substitution Key/Outer Key
```
((s0 ^ s1) < o0) == ((s0 < o0) ^ (s1 < o0))
```
#### Substitution Key/Inner Key
```
((s0 ^ s1) << i0) == ((s0 << i0) ^ (s1 << i0))
```
#### Substitution Key/Inner Key/Outer Key
```
((s0 << i0) < o0) == ((s0 < o0) << (i0 < o0))
```
### Other Examples
```
(s0 << (i0 < o0)) == (((s0 < ~o0) << i0) < o0)
((s0 < o0) << i0) == ((s0 << (i0 < ~o0)) < o0)
(~(i0 << i1)) == (~i1 << ~i0)
(~(o0 << o1)) == (~o1 << ~o0)
i0 == ((i0 << i2 << i1) << ~(i2 << i1)) == ((i0 << i2 << i1) << ~i1 << ~i2)
```
### Becareful about your order of operation
***Always use parenthesis to control the order of operation***
```
i0 < (o0 << o1 << o2) != (i0 < (o0 << o1 << o2)) # not equal !!!!!!
```