Skip to content

Instantly share code, notes, and snippets.

  • Save Twilight-Dream-Of-Magic/776c44ae4c8eda7f1c2be4faf38f201b to your computer and use it in GitHub Desktop.
Save Twilight-Dream-Of-Magic/776c44ae4c8eda7f1c2be4faf38f201b to your computer and use it in GitHub Desktop.

Hexagonal symmetric encryption and decryption structure and algorithm implementation based on artificial intelligence neural network idea

1. Diagram of the Hexagonal Neural Network Structure

Simple Version

`#` is Empty data

                                PlainText    PlainText
                                       |       |
                                       |       |
                                       |       |
                                       |       |
*Round Key 1*                          |       |
 --Branching-->                        F1     F1
                                      / \     / \
                                    /     \ /     \
                                {#, A}   {B, C}  {D, #} 
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                    \     / \     /
*Round Key 2*                         \ /     \ /
--Merging-->                        F1^{-1} F1^{-1}
                                       |       |        
                                       |       |     
                                       |       |     
-Invertible Mix->                      F2      F2
                                       |       |
                                       |       |
*Round Key 3*                          |       |  
--Branching-->                         F1      F1    
                                      / \     / \
                                    /     \ /     \
                                {#, A'} {B', C'} {D', #} 
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                    \     / \     /
*Round Key 4*                         \ /     \ /
--Merging-->                        F1^{-1} F1^{-1}
                                       |       |
                                       |       |
                                       |       |
                                       |       |
                                       |       |                                                                              
                                CipherText   CipherText

(Round 1)

Detail Version

Encryption:
------------
PlainText1, PlainText2, PlainText3, PlainText4
      |
      v
F1_branch (Split into A, B, C, D, E, F, G, H)
      |
      v
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |   \         /   |   \         /   |   \         /   |
      |    \       /    |    \       /    |    \       /    |
      |     \     /     |     \     /     |     \     /     |
      |      \   /      |      \   /      |      \   /      |
      |       \ /       |       \ /       |       \ /       |
      |        *        |        *        |        *        |  <--- The intersections in the middle are denoted by *. there's a 50% probability of the data being obfuscated by the (F2) function `if RandomNumber & 1`
      |       / \       |       / \       |       / \       |
      |      /   \      |      /   \      |      /   \      |
      |     /     \     |     /     \     |     /     \     |
      |    /       \    |    /       \    |    /       \    |
      |   /         \   |   /         \   |   /         \   |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |
      v
InvertiblePermutation
      |
      v
F1_merge
      |
      v
CipherText1, CipherText2, CipherText3, CipherText4


Decryption:
------------
CipherText1, CipherText2, CipherText3, CipherText4
      |
      v
F1_branch (Split into A, B, C, D, E, F, G, H)
      |
      v
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |   \         /   |   \         /   |   \         /   |
      |    \       /    |    \       /    |    \       /    |
      |     \     /     |     \     /     |     \     /     |
      |      \   /      |      \   /      |      \   /      |
      |       \ /       |       \ /       |       \ /       |
      |        *        |        *        |        *        |  <--- The intersections in the middle are denoted by *. there's a 50% probability of the data being obfuscated by the (F2_inverse) function `if RandomNumber & 1`
      |       / \       |       / \       |       / \       |
      |      /   \      |      /   \      |      /   \      |
      |     /     \     |     /     \     |     /     \     |
      |    /       \    |    /       \    |    /       \    |
      |   /         \   |   /         \   |   /         \   |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |
      v
InvertiblePermutationInverse
      |
      v
F1_merge
      |
      v
PlainText1, PlainText2, PlainText3, PlainText4

2. Background and Inspiration

The concept of intertwining neural network structures with cryptographic techniques is not just a mere fusion of two disparate fields, but a testament to the evolving nature of cryptography. Neural networks, with their intricate interconnections and adaptive learning capabilities, have revolutionized areas like image processing, natural language understanding, and predictive analytics. The hexagonal structure, inspired by these networks, aims to bring a similar revolution to the world of cryptography.

The hexagonal design is not just a stylistic choice. Hexagons, due to their six-sided nature, offer a geometric advantage by allowing more pathways and connections compared to other shapes. This geometric property translates to a cryptographic advantage, providing more avenues for data mixing, increasing confusion, and enhancing the overall security of the encryption process.

3. Reference to Traditional Symmetric Encryption and Decryption Structures

The hexagonal neural network structure, while novel, stands on the shoulders of cryptographic giants. It incorporates principles from traditional symmetric encryption schemes, particularly the Feistel network and the Lai-Massey scheme.

The Feistel network, a structure that underpins algorithms like DES, involves the bifurcation of data into two halves, with each half undergoing a series of transformations influenced by the other half and a subkey. Our hexagonal design mirrors this with its branching and merging operations.

The Lai-Massey scheme, another symmetric encryption structure, is known for its two rounds of encryption with a central swapping operation. This scheme enhances the diffusion properties of the encryption, a feature that our hexagonal structure aims to emulate with its "Invertible Mix Function".

4. Mathematical Principles and Structure Description

The hexagonal neural network structure is a blend of mathematical operations and algorithmic flow, each designed for cryptographic robustness:

1. Branching (F1_branch):

The branching operation is a bifurcation function that splits an input data block into two distinct parts. This operation can be represented mathematically as: [ (A, B) = F1_{branch}(PlainText, Key) ] Where (PlainText) is the input data, (Key) is the cryptographic key used for the operation, and (A) and (B) are the resultant bifurcated parts.

2. Merging (F1_merge):

The merging operation amalgamates two parts into a single data block. This function can be represented as: [ CipherText = F1_{merge}(A, B, Key) ] Where (A) and (B) are the input parts, (Key) is the cryptographic key, and (CipherText) is the resultant merged data.

3. Invertible Mix Function (F2):

This function is central to the diffusion property of the encryption. It shuffles the bits of a data block in a predetermined, reversible manner. The mathematical representation is: [ MixedData = F2(Data) ] [ Data = F2^{-1}(MixedData) ] Where (Data) is the input data block, (MixedData) is the shuffled data, and (F2^{-1}) is the inverse function that undoes the shuffle.

Algorithmic Flow:

  1. Initialization:

    • Input two blocks of plaintext: (PlainText_1) and (PlainText_2).
    • Define a key set: (Key).
    • Generate a random number: (RandomNumber).
  2. Branching:

    • Split (PlainText_1) into (A) and (B).
    • Split (PlainText_2) into (C) and (D).
  3. Conditional Mixing:

    • With a 50% probability (determined by the condition RandomNumber & 1):
      • Merge (B) and (C) to form (Merged).
      • Apply the invertible mix function (F2) on (Merged).
      • Branch (Merged) to get the new (B) and (C).
  4. Permutation:

    • Apply the InvertiblePermutation function on (A, B, C, D).
  5. Merging:

    • Merge (A) and (B) to get (CipherText_1).
    • Merge (C) and (D) to get (CipherText_2).
  6. Output:

    • Return (CipherText_1) and (CipherText_2).

The decryption process follows the inverse of the above steps, ensuring the reversibility of the encryption.

5.Formal Safety Analysis of the Hexagonal Neural Network Structure

Background and Inspiration

The hexagonal neural network structure for symmetric encryption is a novel approach that draws inspiration from both neural networks and traditional cryptographic designs. Neural networks, with their interconnected nodes and layers, offer a unique perspective on data transformation. This concept, when applied to cryptography, can lead to intricate data flow and transformation, making it challenging for adversaries to decipher without the correct key.

Furthermore, the design also references traditional cryptographic structures, notably the Lai-Massey scheme and the Feistel network. The Lai-Massey scheme is known for its split-function design, which is evident in the branching and merging operations of the hexagonal structure. The Feistel network, with its rounds of permutation and substitution, is mirrored in the hexagonal structure's rounds of confusion and diffusion.

Mathematical Principles and Algorithmic Flow

The hexagonal neural network structure operates on several mathematical and cryptographic principles:

  1. Branching and Merging: At its core, the structure uses a split-function design, similar to the Lai-Massey scheme. Data is split into parts (e.g., A and B), processed separately, and then merged. This operation ensures that the data is continuously transformed and mixed.

  2. Conditional Confusion: The structure introduces confusion based on a conditional probability. Specifically, the operation if RandomNumber & 1 ensures a 50% probability scenario. This randomness ensures that the encryption process isn't deterministic, adding another layer of complexity.

  3. Diffusion and key based confusion via Invertible Mix Function: The Invertible mix function ensures that a change in one bit of the input leads to changes in multiple bits of the output. This property is crucial for ensuring that the ciphertext doesn't reveal any patterns about the plaintext.

  4. Final Shuffle Step: After the hexagonal confusion, a final shuffle step ensures that the ciphertext is free from any patterns specific to the hexagonal design. This step is crucial for ensuring the unpredictability and security of the encryption.

Evaluation

The hexagonal neural network structure, with its intricate design and multiple layers of confusion and diffusion, holds promise in the realm of symmetric encryption. Its strengths lie in its layered approach, conditional operations, and versatility. However, potential weaknesses, such as performance overhead and dependency on a random number generator, need to be addressed.

Argument

The introduction of a neural network-inspired design in cryptography is a fresh perspective. While traditional cryptographic structures like the Lai-Massey scheme and Feistel network have proven their worth, the hexagonal neural network structure offers a new avenue for exploration. Its interconnected design ensures thorough confusion and diffusion, two pillars of symmetric encryption. The conditional operations introduce unpredictability, while the final shuffle step ensures the ciphertext's randomness. However, like all cryptographic designs, it needs rigorous testing and cryptanalysis to ascertain its resilience against various attacks.


基于人工智能神经网络思想的六边形对称加解密结构和算法实现

1. 六边形神经网络结构图

简单版本

`#` is Empty data

                                PlainText    PlainText
                                       |       |
                                       |       |
                                       |       |
                                       |       |
*Round Key 1*                          |       |
 --Branching-->                        F1     F1
                                      / \     / \
                                    /     \ /     \
                                {#, A}   {B, C}  {D, #} 
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                    \     / \     /
*Round Key 2*                         \ /     \ /
--Merging-->                        F1^{-1} F1^{-1}
                                       |       |        
                                       |       |     
                                       |       |     
-Invertible Mix->                      F2      F2
                                       |       |
                                       |       |
*Round Key 3*                          |       |  
--Branching-->                         F1      F1    
                                      / \     / \
                                    /     \ /     \
                                {#, A'} {B', C'} {D', #} 
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                  | |     | |     | |
                                    \     / \     /
*Round Key 4*                         \ /     \ /
--Merging-->                        F1^{-1} F1^{-1}
                                       |       |
                                       |       |
                                       |       |
                                       |       |
                                       |       |                                                                              
                                CipherText   CipherText

(Round 1)

详细版本

加密:
------------
PlainText1, PlainText2, PlainText3, PlainText4
      |
      v
F1_branch (拆分为 A, B, C, D, E, F, G, H)
      |
      v
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |   \         /   |   \         /   |   \         /   |
      |    \       /    |    \       /    |    \       /    |
      |     \     /     |     \     /     |     \     /     |
      |      \   /      |      \   /      |      \   /      |
      |       \ /       |       \ /       |       \ /       |
      |        *        |        *        |        *        |  <--- 中间的交叉点用 * 表示,数据被 (F2) 函数混淆的概率为 50%。 `if RandomNumber & 1`
      |       / \       |       / \       |       / \       |
      |      /   \      |      /   \      |      /   \      |
      |     /     \     |     /     \     |     /     \     |
      |    /       \    |    /       \    |    /       \    |
      |   /         \   |   /         \   |   /         \   |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |
      v
InvertiblePermutation
      |
      v
F1_merge
      |
      v
CipherText1, CipherText2, CipherText3, CipherText4


解密:
------------
CipherText1, CipherText2, CipherText3, CipherText4
      |
      v
F1_branch (拆分为 A, B, C, D, E, F, G, H)
      |
      v
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |   \         /   |   \         /   |   \         /   |
      |    \       /    |    \       /    |    \       /    |
      |     \     /     |     \     /     |     \     /     |
      |      \   /      |      \   /      |      \   /      |
      |       \ /       |       \ /       |       \ /       |
      |        *        |        *        |        *        |  <--- 中间的交叉点用 * 表示,数据被 (F2) 函数混淆的概率为 50%。 `if RandomNumber & 1`
      |       / \       |       / \       |       / \       |
      |      /   \      |      /   \      |      /   \      |
      |     /     \     |     /     \     |     /     \     |
      |    /       \    |    /       \    |    /       \    |
      |   /         \   |   /         \   |   /         \   |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
|  A  |  B  |     |  C  |  D  |     |  E  |  F  |     |  G  |  H  |
+-----+-----+     +-----+-----+     +-----+-----+     +-----+-----+
      |
      v
InvertiblePermutationInverse
      |
      v
F1_merge
      |
      v
PlainText1, PlainText2, PlainText3, PlainText4

2. 背景与灵感

将神经网络结构与密码学技术交织在一起的概念不仅仅是两个不同领域的融合,它还证明了密码学不断发展的本质。 神经网络具有错综复杂的互连和自适应学习能力,在图像处理、自然语言理解和预测分析等领域带来了革命性的变化。 六边形结构受这些网络的启发,旨在为密码学领域带来类似的变革。

六边形设计不仅仅是一种风格上的选择。 六边形具有六面的特性,与其他形状相比,它具有更多的路径和连接,因而具有几何优势。 这种几何特性转化为加密优势,为数据混合提供了更多途径,增加了混淆性,提高了加密过程的整体安全性。

3. 参考传统的对称加密和解密结构

六边形神经网络结构虽然新颖,但却站在密码学巨人的肩膀上。 它吸收了传统对称加密方案的原理,特别是费斯特尔网络和莱-马西方案。

费斯特尔网络是 DES 等算法的基础结构,它将数据分成两半,每一半数据都会受到另一半数据和子密钥的影响而进行一系列转换。 我们的六边形设计通过分支和合并操作反映了这一点。

Lai-Massey 方案是另一种对称加密结构,以两轮加密和中央交换操作而闻名。 这种方案增强了加密的扩散特性,而我们的六边形结构正是要利用其 "可逆混合函数 "来模仿这种特性。

4. 数学原理和结构描述

六边形神经网络结构是数学运算和算法流程的融合,每一个都设计用于加密的健壮性:

1. 分支 (F1_branch):

分支操作是一种二分函数,将输入数据块分成两个不同的部分。这个操作可以用数学来表示为: [ (A, B) = F1_{branch}(PlainText, Key) ] 其中 (PlainText) 是输入数据,(Key) 是用于操作的加密密钥,而 (A) 和 (B) 是产生的二分部分。

2. 合并 (F1_merge):

合并操作将两个部分合并成一个数据块。这个函数可以表示为: [ CipherText = F1_{merge}(A, B, Key) ] 其中 (A) 和 (B) 是输入部分,(Key) 是加密密钥,而 (CipherText) 是产生的合并数据。

3. 可逆混合函数 (F2):

此函数是加密的扩散属性的中心。它以预定的、可逆的方式洗牌数据块。数学表示为: [ MixedData = F2(Data) ] [ Data = F2^{-1}(MixedData) ] 其中 (Data) 是输入数据块,(MixedData) 是洗牌后的数据,(F2^{-1}) 是撤消洗牌的逆函数。

算法流程:

  1. 初始化:

    • 输入两个明文块: (PlainText_1) 和 (PlainText_2)。
    • 定义一个密钥集: (Key)。
    • 生成一个随机数: (RandomNumber)。
  2. 分支:

    • 将 (PlainText_1) 分成 (A) 和 (B)。
    • 将 (PlainText_2) 分成 (C) 和 (D)。
  3. 条件混合:

    • 根据条件 RandomNumber & 1 的 50% 的概率:
      • 合并 (B) 和 (C) 形成 (Merged)。
      • 对 (Merged) 应用可逆混合函数 (F2)。
      • 将 (Merged) 分支得到新的 (B) 和 (C)。
  4. 置换:

    • 对 (A, B, C, D) 应用 InvertiblePermutation 函数。
  5. 合并:

    • 合并 (A) 和 (B) 得到 (CipherText_1)。
    • 合并 (C) 和 (D) 得到 (CipherText_2)。
  6. 输出:

    • 返回 (CipherText_1) 和 (CipherText_2)。

解密过程遵循上述步骤的逆序,确保加密的可逆性。

5. 六边形神经网络结构的正式安全性分析

背景和灵感

用于对称加密的六边形神经网络结构是一种新颖的方法,它既受到神经网络的启发,也借鉴了传统的加密设计。 神经网络,凭借其相互连接的节点和层,为数据转换提供了独特的视角。 当这一概念应用于加密时,它可以导致复杂的数据流和转换,使得没有正确的密钥的敌手难以解密。

此外,该设计还参考了传统的加密结构,尤其是Lai-Massey方案和Feistel网络。 Lai-Massey方案以其分裂功能设计而著称,这在六边形结构的分支和合并操作中很明显。Feistel网络,其置换和替代的轮次,反映在六边形结构的混淆和扩散轮次中。

数学原理和算法流程

六边形神经网络结构基于几种数学和加密原理进行操作:

  1. 分支和合并:在其核心,该结构使用与Lai-Massey方案相似的分裂功能设计。数据分成几部分(例如,A和B),分别处理,然后合并。此操作确保数据持续地被转换和混合。

  2. 条件混淆:该结构基于条件概率引入混淆。具体来说,if RandomNumber & 1操作确保了50%的概率场景。这种随机性确保加密过程不是确定性的,增加了另一层复杂性。

  3. 通过可逆混合函数实现基于扩散和密钥的混淆可逆混合函数确保输入的一位改变会导致输出的多位改变。这个属性对确保密文不透露明文的任何模式至关重要。

  4. 最终打乱步骤:经过六边形混淆后,最后的打乱步骤确保密文不含有六边形设计的任何特定模式。这一步对确保加密的不可预测性和安全性至关重要。

评估

六边形神经网络结构,凭借其复杂的设计和多层的混淆和扩散,在对称加密领域有着很大的潜力。 其优点在于其分层方法,条件操作和多功能性。然而,需要解决的潜在弱点,如性能开销和对随机数生成器的依赖。

争论

在加密中引入神经网络启发的设计是一个新鲜的观点。 虽然像Lai-Massey方案和Feistel网络这样的传统加密结构已经证明了它们的价值,但六边形神经网络结构为探索提供了一个新的途径。 其相互连接的设计确保了充分的混淆和扩散,这两个都是对称加密的支柱。条件操作引入了不可预测性,而最终的打乱步骤确保了密文的随机性。 然而,像所有的加密设计一样,它需要严格的测试和密码分析来确定其对各种攻击的抵抗力。


6. Implementation (实现)

Python

import random

def F1_branch(input_data, key):
    A = (input_data & 0xFFFFFFFF00000000) >> 32
    B = input_data & 0x00000000FFFFFFFF
    
    key_A = (key & 0xFFFFFFFF00000000) >> 32
    key_B = key & 0x00000000FFFFFFFF
    A = A ^ key_A
    B = B ^ key_B
    
    return A, B

def F1_merge(A, B, key):
    combined_data = (A << 32) | B
    return combined_data ^ key

PERMUTATION_TABLE = [
    63, 0, 62, 1, 61, 2, 60, 3, 59, 4, 58, 5, 57, 6, 56, 7,
    55, 8, 54, 9, 53, 10, 52, 11, 51, 12, 50, 13, 49, 14, 48, 15,
    47, 16, 46, 17, 45, 18, 44, 19, 43, 20, 42, 21, 41, 22, 40, 23,
    39, 24, 38, 25, 37, 26, 36, 27, 35, 28, 34, 29, 33, 30, 32, 31
]

INVERSE_PERMUTATION_TABLE = [0] * 64

def F2(input_data):
    output_data = 0
    for i in range(64):
        if (input_data & (1 << i)):
            output_data |= (1 << PERMUTATION_TABLE[i])
    return output_data

def F2_inverse(input_data):
    output_data = 0
    for i in range(64):
        if (input_data & (1 << i)):
            output_data |= (1 << INVERSE_PERMUTATION_TABLE[i])
    return output_data

def initialize_inverse_permutation_table():
    for i in range(64):
        INVERSE_PERMUTATION_TABLE[PERMUTATION_TABLE[i]] = i

def InvertiblePermutation(A, B, C, D):
    return B, C, D, A

def InvertiblePermutationInverse(A, B, C, D):
    return D, A, B, C

def encrypt_two(PlainText1, PlainText2, Key, seed):
    random.seed(seed)
    RandomNumber = random.randint(0, 0xFFFFFFFFFFFFFFFF)
    
    A, B = F1_branch(PlainText1, Key[1])
    C, D = F1_branch(PlainText2, Key[3])

    # Conditional Confusion and Diffusion in one loop
    if RandomNumber & 1:
        # Head Layer
        Merged = F1_merge(B, C, Key[2])
        # Hidden layer (use an invertible function here)
        Merged = F2(Merged)
        # Tail Layer
        B, C = F1_branch(Merged, Key[2])
    
    A, B, C, D = InvertiblePermutation(A, B, C, D)

    CipherText1 = F1_merge(A, B, Key[0])
    CipherText2 = F1_merge(C, D, Key[4])

    return CipherText1, CipherText2

def decrypt_two(CipherText1, CipherText2, Key, seed):
    random.seed(seed)
    RandomNumber = random.randint(0, 0xFFFFFFFFFFFFFFFF)
    
    A, B = F1_branch(CipherText1, Key[0])
    C, D = F1_branch(CipherText2, Key[4])

    A, B, C, D = InvertiblePermutationInverse(A, B, C, D)
    
    # Conditional Confusion and Diffusion in one loop
    if RandomNumber & 1:
        # Head Layer
        Merged = F1_merge(B, C, Key[2])
        # Hidden layer (use an invertible function here)
        Merged = F2_inverse(Merged)
        # Tail Layer
        B, C = F1_branch(Merged, Key[2])

    PlainText1 = F1_merge(A, B, Key[1])
    PlainText2 = F1_merge(C, D, Key[3])

    return PlainText1, PlainText2

def encrypt_sixteen(PlainTexts, Key, seed):
    random.seed(seed)
    CipherTexts = []

    for idx in range(0, 16, 2):
        RandomNumber = random.randint(0, 0xFFFFFFFFFFFFFFFF)
        A, B = F1_branch(PlainTexts[idx], Key[2 * idx + 1])
        C, D = F1_branch(PlainTexts[idx + 1], Key[2 * (idx + 1) + 1])

        # Conditional Confusion and Diffusion in one loop
        if RandomNumber & 1:
            # Head Layer
            Merged = F1_merge(B, C, Key[2 * idx + 2])
            # Hidden layer (use an invertible function here)
            Merged = F2(Merged)
            # Tail Layer
            B, C = F1_branch(Merged, Key[2 * idx + 2])
        
        A, B, C, D = InvertiblePermutation(A, B, C, D)

        CipherText1 = F1_merge(A, B, Key[2 * idx])
        CipherText2 = F1_merge(C, D, Key[2 * (idx + 1)])

        CipherTexts.append(CipherText1)
        CipherTexts.append(CipherText2)

    return CipherTexts

def decrypt_sixteen(CipherTexts, Key, seed):
    random.seed(seed)
    PlainTexts = []

    for idx in range(0, 16, 2):
        RandomNumber = random.randint(0, 0xFFFFFFFFFFFFFFFF)
        A, B = F1_branch(CipherTexts[idx], Key[2 * idx])
        C, D = F1_branch(CipherTexts[idx + 1], Key[2 * (idx + 1)])

        A, B, C, D = InvertiblePermutationInverse(A, B, C, D)
        
        # Conditional Confusion and Diffusion in one loop
        if RandomNumber & 1:
            # Head Layer
            Merged = F1_merge(B, C, Key[2 * idx + 2])
            # Hidden layer (use an invertible function here)
            Merged = F2_inverse(Merged)
            # Tail Layer
            B, C = F1_branch(Merged, Key[2 * idx + 2])

        PlainText1 = F1_merge(A, B, Key[2 * idx + 1])
        PlainText2 = F1_merge(C, D, Key[2 * (idx + 1) + 1])

        PlainTexts.append(PlainText1)
        PlainTexts.append(PlainText2)

    return PlainTexts

if __name__ == "__main__":
    initialize_inverse_permutation_table()

    # Test for encrypt_two and decrypt_two
    Key = [0xABCD, 0xFDEC, 0x5678, 0x1234, 0x89AB]
    PlainText1 = 0x1234
    PlainText2 = 0x5678
    seed = 42

    EncryptedText1, EncryptedText2 = encrypt_two(PlainText1, PlainText2, Key, seed)
    DecryptedText1, DecryptedText2 = decrypt_two(EncryptedText1, EncryptedText2, Key, seed)

    assert (DecryptedText1, DecryptedText2) == (PlainText1, PlainText2)
    print("PlainText1:", PlainText1)
    print("PlainText2:", PlainText2)
    print("EncryptedText1:", EncryptedText1)
    print("EncryptedText2:", EncryptedText2)
    print("DecryptedText1:", DecryptedText1)
    print("DecryptedText2:", DecryptedText2)

    # Test for encrypt_sixteen and decrypt_sixteen
    Key16 = [
        0xABCD, 0xFDEC, 0x5678, 0x1234, 0x89AB, 0x4321, 0x8765, 0xDCBA,
        0xEF01, 0x2345, 0x6789, 0x0ABC, 0xDEFA, 0xBCDE, 0xF012, 0x3456,
        0x789A, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567,
        0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567
    ]
    PlainTexts = [0x1234 + i for i in range(16)]

    EncryptedTexts = encrypt_sixteen(PlainTexts, Key16, seed)
    DecryptedTexts = decrypt_sixteen(EncryptedTexts, Key16, seed)

    assert DecryptedTexts == PlainTexts
    print("\nPlainTexts:")
    for pt in PlainTexts:
        print(pt, end=" ")
    print("\nEncryptedTexts:")
    for et in EncryptedTexts:
        print(et, end=" ")
    print("\nDecryptedTexts:")
    for dt in DecryptedTexts:
        print(dt, end=" ")
    print()

While the Python implementation has been detailed previously, translating this to C++ would involve leveraging libraries like bitset for bitwise operations and ensuring type safety. The C++ version would also benefit from optimizations that the language inherently offers, especially when dealing with low-level operations. 虽然 Python 的实现已在之前详细介绍过,但将其转换为 C++ 将涉及到利用bitset等库进行位操作,并确保类型安全。 C++ 版本还将受益于该语言固有的优化功能,尤其是在处理底层操作时。

C++

#include <iostream>
#include <cstdint>
#include <vector>
#include <cassert>
#include <random>
#include <tuple>

// Assuming input_data is a 64-bit number and key is also a 64-bit number
std::pair<uint32_t, uint32_t> F1_branch(uint64_t input_data, uint64_t key) {
    uint32_t A = (input_data & 0xFFFFFFFF00000000) >> 32;
    uint32_t B = input_data & 0x00000000FFFFFFFF;
    
    uint32_t key_A = (key & 0xFFFFFFFF00000000) >> 32;
    uint32_t key_B = key & 0x00000000FFFFFFFF;
    A = A ^ key_A;
    B = B ^ key_B;
    
    return {A, B};
}

uint64_t F1_merge(uint32_t A, uint32_t B, uint64_t key) {
    uint64_t combined_data = ((uint64_t)A << 32) | B;
    return combined_data ^ key;
}

// Fixed permutation table for a 64-bit input
const int PERMUTATION_TABLE[64] = {
    63, 0, 62, 1, 61, 2, 60, 3, 59, 4, 58, 5, 57, 6, 56, 7,
    55, 8, 54, 9, 53, 10, 52, 11, 51, 12, 50, 13, 49, 14, 48, 15,
    47, 16, 46, 17, 45, 18, 44, 19, 43, 20, 42, 21, 41, 22, 40, 23,
    39, 24, 38, 25, 37, 26, 36, 27, 35, 28, 34, 29, 33, 30, 32, 31
};

int INVERSE_PERMUTATION_TABLE[64];

uint64_t F2(uint64_t input_data) {
    uint64_t output_data = 0;
    for (int i = 0; i < 64; ++i) {
        if (input_data & (1ULL << i)) {
            output_data |= (1ULL << PERMUTATION_TABLE[i]);
        }
    }
    return output_data;
}

uint64_t F2_inverse(uint64_t input_data) {
    uint64_t output_data = 0;
    for (int i = 0; i < 64; ++i) {
        if (input_data & (1ULL << i)) {
            output_data |= (1ULL << INVERSE_PERMUTATION_TABLE[i]);
        }
    }
    return output_data;
}

// Initialize the inverse permutation table
void initialize_inverse_permutation_table() {
    for (int i = 0; i < 64; ++i) {
        INVERSE_PERMUTATION_TABLE[PERMUTATION_TABLE[i]] = i;
    }
}

std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> InvertiblePermutation(uint32_t A, uint32_t B, uint32_t C, uint32_t D) {
    return {B, C, D, A};
}

std::tuple<uint32_t, uint32_t, uint32_t, uint32_t> InvertiblePermutationInverse(uint32_t A, uint32_t B, uint32_t C, uint32_t D) {
    return {D, A, B, C};
}

std::pair<uint64_t, uint64_t> encrypt_two(uint64_t PlainText1, uint64_t PlainText2, const std::vector<uint64_t>& Key, int seed) {
    std::mt19937_64 gen(seed);
    std::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFF);
    uint32_t RandomNumber = dist(gen);
    
    auto [A, B] = F1_branch(PlainText1, Key[1]);
    auto [C, D] = F1_branch(PlainText2, Key[3]);

    if (RandomNumber & 1) {
        //Head Layer
        uint64_t Merged = F1_merge(B, C, Key[2]);
        //Hidden layer (while any complex function can be used, the function should be made invertible)
        Merged = F2(Merged);
        //Tail Layer
        std::tie(B, C) = F1_branch(Merged, Key[2]);
    }
    std::tie(A, B, C, D) = InvertiblePermutation(A, B, C, D);

    uint64_t CipherText1 = F1_merge(A, B, Key[0]);
    uint64_t CipherText2 = F1_merge(C, D, Key[4]);

    return {CipherText1, CipherText2};
}

std::pair<uint64_t, uint64_t> decrypt_two(uint64_t CipherText1, uint64_t CipherText2, const std::vector<uint64_t>& Key, int seed) {
    std::mt19937_64 gen(seed);
    std::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFF);
    uint32_t RandomNumber = dist(gen);
    
    auto [A, B] = F1_branch(CipherText1, Key[0]);
    auto [C, D] = F1_branch(CipherText2, Key[4]);

    std::tie(A, B, C, D) = InvertiblePermutationInverse(A, B, C, D);
    if (RandomNumber & 1) {
        //Head Layer
        uint64_t Merged = F1_merge(B, C, Key[2]);
        //Hidden layer (while any complex function can be used, the function should be made invertible)
        Merged = F2_inverse(Merged);
        //Tail Layer
        std::tie(B, C) = F1_branch(Merged, Key[2]);
    }

    uint64_t PlainText1 = F1_merge(A, B, Key[1]);
    uint64_t PlainText2 = F1_merge(C, D, Key[3]);

    return {PlainText1, PlainText2};
}

std::vector<uint64_t> encrypt_sixteen(const std::vector<uint64_t>& PlainTexts, const std::vector<uint64_t>& Key, int seed) {
    std::mt19937 gen(seed);
    std::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFF);
    
    std::vector<uint64_t> CipherTexts;
    
    for (size_t idx = 0; idx < 16; idx += 2) {
        uint64_t RandomNumber = dist(gen);
        auto [A, B] = F1_branch(PlainTexts[idx], Key[2*idx + 1]);
        auto [C, D] = F1_branch(PlainTexts[idx+1], Key[2*(idx+1) + 1]);
        
        if (RandomNumber & 1) {
            //Head Layer
            uint64_t Merged = F1_merge(B, C, Key[2*idx + 2]);
            //Hidden layer (while any complex function can be used, the function should be made invertible)
            Merged = F2(Merged);
            //Tail Layer
            std::tie(B, C) = F1_branch(Merged, Key[2*idx + 2]);
        }
        std::tie(A, B, C, D) = InvertiblePermutation(A, B, C, D);

        uint64_t CipherText1 = F1_merge(A, B, Key[2*idx]);
        uint64_t CipherText2 = F1_merge(C, D, Key[2*(idx+1)]);
        
        CipherTexts.push_back(CipherText1);
        CipherTexts.push_back(CipherText2);
    }

    return CipherTexts;
}

std::vector<uint64_t> decrypt_sixteen(const std::vector<uint64_t>& CipherTexts, const std::vector<uint64_t>& Key, int seed) {
    std::mt19937 gen(seed);
    std::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFF);
    
    std::vector<uint64_t> PlainTexts;
    
    for (size_t idx = 0; idx < 16; idx += 2) {
        uint64_t RandomNumber = dist(gen);
        auto [A, B] = F1_branch(CipherTexts[idx], Key[2*idx]);
        auto [C, D] = F1_branch(CipherTexts[idx+1], Key[2*(idx+1)]);

        std::tie(A, B, C, D) = InvertiblePermutationInverse(A, B, C, D);
        if (RandomNumber & 1) {
            //Head Layer
            uint64_t Merged = F1_merge(B, C, Key[2*idx + 2]);
            //Hidden layer (while any complex function can be used, the function should be made invertible)
            Merged = F2_inverse(Merged);
            //Tail Layer
            std::tie(B, C) = F1_branch(Merged, Key[2*idx + 2]);
        }

        uint64_t PlainText1 = F1_merge(A, B, Key[2*idx + 1]);
        uint64_t PlainText2 = F1_merge(C, D, Key[2*(idx+1) + 1]);
        
        PlainTexts.push_back(PlainText1);
        PlainTexts.push_back(PlainText2);
    }

    return PlainTexts;
}

int main() {
    initialize_inverse_permutation_table();

    // Test for encrypt_two and decrypt_two
    std::vector<uint64_t> Key = {0xABCD, 0xFDEC, 0x5678, 0x1234, 0x89AB};
    uint64_t PlainText1 = 0x1234;
    uint64_t PlainText2 = 0x5678;
    int seed = 42;

    auto [EncryptedText1, EncryptedText2] = encrypt_two(PlainText1, PlainText2, Key, seed);
    auto [DecryptedText1, DecryptedText2] = decrypt_two(EncryptedText1, EncryptedText2, Key, seed);

    assert(std::make_pair(DecryptedText1, DecryptedText2) == std::make_pair(PlainText1, PlainText2));
    std::cout << "PlainText1: " << PlainText1 << "\n";
    std::cout << "PlainText2: " << PlainText2 << "\n";
    std::cout << "EncryptedText1: " << EncryptedText1 << "\n";
    std::cout << "EncryptedText2: " << EncryptedText2 << "\n";
    std::cout << "DecryptedText1: " << DecryptedText1 << "\n";
    std::cout << "DecryptedText2: " << DecryptedText2 << "\n";

    // Test for encrypt_sixteen and decrypt_sixteen
    std::vector<uint64_t> Key16 = {
        0xABCD, 0xFDEC, 0x5678, 0x1234, 0x89AB, 0x4321, 0x8765, 0xDCBA,
        0xEF01, 0x2345, 0x6789, 0x0ABC, 0xDEFA, 0xBCDE, 0xF012, 0x3456,
        0x789A, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567,
        0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567
    };
    std::vector<uint64_t> PlainTexts;
    for (int i = 0; i < 16; ++i) {
        PlainTexts.push_back(0x1234 + i);
    }

    std::vector<uint64_t> EncryptedTexts = encrypt_sixteen(PlainTexts, Key16, seed);
    std::vector<uint64_t> DecryptedTexts = decrypt_sixteen(EncryptedTexts, Key16, seed);

    assert(DecryptedTexts == PlainTexts);
    std::cout << "\nPlainTexts:\n";
    for (const auto& pt : PlainTexts) {
        std::cout << pt << " ";
    }
    std::cout << "\nEncryptedTexts:\n";
    for (const auto& et : EncryptedTexts) {
        std::cout << et << " ";
    }
    std::cout << "\nDecryptedTexts:\n";
    for (const auto& dt : DecryptedTexts) {
        std::cout << dt << " ";
    }
    std::cout << std::endl;

    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment