Last active
March 28, 2024 16:10
-
-
Save Twilight-Dream-Of-Magic/d269786a59a53f60ab79797cd84f268a to your computer and use it in GitHub Desktop.
LittleOaldresPuzzle_Cryptic StreamCipher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from mpmath import mp | |
# Set the desired decimal precision | |
mp.dps = 100 | |
# Define the mathematical constants | |
e = mp.e | |
pi = mp.pi | |
phi = (1 + mp.sqrt(5)) / 2 | |
sqrt_2 = mp.sqrt(2) | |
sqrt_3 = mp.sqrt(3) | |
gamma = mp.mpf("0.5772156649") # Euler–Mascheroni constant | |
delta = mp.mpf("4.6692016091") # Feigenbaum constant | |
rho = mp.mpf("1.3247179572") # Plastic number | |
''' | |
e = mp.e | |
pi = mp.pi | |
phi = (1 + mp.sqrt(5)) / 2 | |
sqrt_2 = mp.sqrt(2) | |
sqrt_3 = mp.sqrt(3) | |
gamma = mp.euler # Euler–Mascheroni constant | |
delta = mp.mpf('4.669201609102990671853203820466') # Feigenbaum constant delta | |
rho = mp.cbrt((9 + mp.sqrt(69)) / 18) + mp.cbrt((9 - mp.sqrt(69)) / 18) # Plastic number | |
''' | |
print(str(e) + '\n') | |
print(str(pi) + '\n') | |
print(str(phi) + '\n') | |
print(str(sqrt_2) + '\n') | |
print(str(sqrt_3) + '\n') | |
print(str(gamma) + '\n') | |
print(str(delta) + '\n') | |
print(str(rho) + '\n') | |
def f(x): | |
x = mp.mpf(x) | |
term1 = (e ** x - mp.cos(pi * x)) | |
term2 = (phi * x ** 2 - phi * x - 1) | |
term3 = (x * sqrt_2 - mp.floor(x * sqrt_2)) | |
term4 = (x * sqrt_3 - mp.floor(x * sqrt_3)) | |
term5 = mp.log(1 + x) | |
term6 = (x * delta - mp.floor(x * delta)) | |
term7 = (x * rho - mp.floor(x * rho)) | |
return term1 * term2 * term3 * term4 * term5 * term6 * term7 | |
def print_console(): | |
round = 1 | |
binary_string = "" | |
for index in range(150): | |
# Calculate the result for a given input value | |
result = f(round) | |
print("Round: ", index) | |
# Print the decimal result | |
print("Decimal number:", result) | |
# Convert the fractional part to binary and print it | |
fractional_part = result - mp.floor(result) | |
binary_fractional_part = format(int(fractional_part * 2**128), 'b') # Using 128 bits of precision for the binary representation | |
# print("Binary representation of fractional part:", binary_fractional_part) | |
# Convert the fractional part to hexadecimal and print it | |
hexadecimal_fractional_part = format(int(fractional_part * 2**128), 'x') | |
print("Hexadecimal representation of fractional part:", hexadecimal_fractional_part) | |
# Print the integer part | |
integer_part = int(result) | |
print("Integer part:", integer_part) | |
round += 1 | |
binary_string += (binary_fractional_part) | |
print("Binary String: ", binary_string) | |
# Convert the binary string to an integer | |
integer_value = int(binary_string, 2) | |
# Convert the integer to a hexadecimal string | |
hexadecimal_string = format(integer_value, 'x') | |
print("Hexadecimal representation:", hexadecimal_string) | |
grouped_hexadecimal_string = ','.join([hexadecimal_string[i:i+16] for i in range(0, len(hexadecimal_string), 16)]) | |
print("Grouped Hexadecimal representation:", grouped_hexadecimal_string) | |
print_console() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import warnings | |
import time | |
warnings.filterwarnings("ignore", category=RuntimeWarning) | |
ROUND_CONSTANT = np.array([#Concatenation of Fibonacci numbers., π, φ, e | |
0x01B70C8E97AD5F98,0x243F6A8885A308D3,0x9E3779B97F4A7C15,0xB7E151628AED2A6A, | |
#x ∈ [1, 138] | |
#f(x) = (e^x - cos(πx)) * (φx^2 - φx - 1) * (√2x - floor(√2x)) * (√3 - floor(√3x)) * ln(1+x) * (xδ - floor(xδ)) * (xρ - floor(xρ)) | |
0x6a433d2ae48d4c90,0x9e2b6e6880ad26da,0x5380e7890f281d86,0x47ea9e01d8ef7c3c, | |
0xb7cfc42c4640a591,0x8ba869f86f575f77,0x66ff83fd9954772c,0x0552755b7ef8c3f6, | |
0xe4931d40d079c5cb,0xd6065bf025a81d13,0x586ceb7761d284af,0x5407a44155b8e341, | |
0x7810f48181dff9e2,0x0f44524582d1d6cf,0x919ad67c2cd7118c,0x926d94a3923cb938, | |
0xc3f400bd67479e59,0x83cb03ba7366b70e,0x629043e6e5712e5c,0x69589ff399736efb, | |
0x834d96f80eea56d7,0x02992cb1835476aa,0x78502c2a1b947013,0xbca81dad05eac8c7, | |
0x43216fe770f57c2d,0x604a5ccfe888eef1,0xfcf5bdd0ea8a112c,0xeb13dc4ba7327617, | |
0xf8587cc0dd587813,0x092b98e058140b26,0x1e044153ec902650,0xd13ef3afb71efc3e, | |
0x55af3f5bca28309e,0xcf478054be1173c8,0x99bb2b591f35ac72,0xd3f5e092a0c7c2bb, | |
0xdc120bced1935766,0xbb2525cf28193ea8,0x6a06eb360550e537,0x4501817d5023f9bb, | |
0x6c9e6ef207e06420,0xa12e023656301669,0x2692fa5ed25b6a2b,0xeb48ef08fd6fbdb7, | |
0xfe8db57151c600fb,0x51197bfba60c36ff,0xe95328ef18701542,0x0663e86118debfdd, | |
0xee0b0fcbaf12d0d0,0xc92c72f7a14c35ea,0x21ca0bd30529c74c,0x70243d7854330319, | |
0x193b70b72995d737,0xa936acbbbe88f426,0x61da22530a461898,0x49afa0f477bda24c, | |
0x795bbbc0bf0cdc23,0x3b5f4cf676e0fc41,0xdeec67413dc24105,0x1af46f766498679d, | |
0xa9f37172c15f8e20,0x292b237adf6467a9,0x09538ddc3733c79e,0xde5c2f22b2c1aa42, | |
0x6204c7ebee5a90d8,0x4359ac75de286849,0x7e616650ab318ae8,0xd7552e509ab0d5a6, | |
0xffaf2a408f8cfa95,0x4289e66a0b74427e,0xc5e9869af1856c6d,0x336aa2e2b3dbfeda, | |
0x9835ff10bf4b7e3c,0xc0c5d995789a9c04,0x09dce0a22fccbe60,0x7cc16b5458b38ec9, | |
0x880d6019ab1aa3fa,0xb9ac43e6d90c89dc,0xe0c876bea28b38be,0xafca75b1c80bc8fa, | |
0xf4e5b08059acb0bd,0x643587ac551f3aa0,0x83fa523817844ac9,0x3e97eca86cc41268, | |
0xd53517b095a47a79,0x418aaab53810d432,0xde9ad8739ba769b7,0x6f53b6fb08b9809c, | |
0xe5d41d82eb6a0d63,0x42137200d3b75b64,0x9ee670cd25143c29,0xdc2b3edf3617c034, | |
0xf5d6d70093472506,0xeaca4e8f7eaa4b68,0x0e7b78a6eca0e67e,0x67db9133f144d92d, | |
0xa2f043bdf0bfc70d,0x679513157c68480e,0xc7359f77d43ecedb,0xa73610dd579db5e8, | |
0xd33f00a73c40b3f4,0x1f6693cdc79f41cf,0x402aba3326ff09e4,0xc2f06d96a33ed417, | |
0x16882cd0ac38796e,0xde2342960e538c6e,0xee16a05c0f946350,0xb76895e14d9f81b0, | |
0x8d8e566bbc5b2b65,0x1b1881ca8831ba3c,0x0fb99dab44900c06,0x51701c39eabb7550, | |
0x98c5cadd4f0446cd,0x12cd6ac42824463f,0x815f799d0d2b6b8d,0xd34bed6a3284fb8f, | |
0x1f4f71425e521345,0x5ec3427cc37ef4b7,0x41ca4c3fbb4ae014,0x4d4a5a8399958a44, | |
0x6f21b526d0c7ee3c,0xe85d52cfba2818c0,0x09d0b2cc4deccc35,0x1b13c064ccec4d2e, | |
0x92b538d3b747c6ac,0x58719d59011b3fae,0xedde21671368f97e,0xfc4dbeff22c77aab, | |
0x66997342600d0997,0x6a173e62da2821d7,0xe657b797f1f23506,0x7052226e4dde4ce0, | |
0xcec9d219091d3713,0x46b20fcd9abd9b13,0x0a8bbb7b077261a8,0x8cf03c3c366533db, | |
0x9d167cec4a7f4953,0xed8bbf927c48dbf9,0x21e8d4a1dd84e782,0x4ac104ee6fa65e69, | |
0x5cb955963da25bee,0xa0f791f755ed9ead,0x1125fa77491b7c6a,0x3c0560dc8d08a6b6, | |
0x20cb39c7b8690d0c,0x29a3a26ccc8540de,0x3ba44a4cbb906982,0xddf9454bc0acb110, | |
0xa989a47d915cc360,0xb90af4a05b78e702,0x7f20b78fb8d8eae8,0xedb6cb8180b81603, | |
0xdfe86decf8f940b5,0x4c6baf1de449fc4d,0x165f86d08961df51,0x4c038e6a96040825, | |
0xf4f2cb95b6276944,0xe7f98f0aae90ff54,0xd90fc39cae09f82e,0x45ef9b03350e102c, | |
0xba319140b8a35152,0xa1c8bf3071254d17,0x6d942b49712b2ff0,0x687ab4e1a35f3a7f, | |
0x8fa2a50edfdfce2d,0x1b123d5c5ba08e5b,0x287209f7e4ad4cd4,0xaae61796f1414dd9, | |
0xabd88a4167ec1728,0x584654213d59d9ac,0x1010e8491f4e2d7d,0x01b6087b68d105e5, | |
0xd478306668f2aed3,0x35b78cf5c30272db,0x4e9b1bd35706711d,0xfbee714f84a270e5, | |
0x8855b3fe8d108055,0x1829c0415ef92080,0x2a6238b05b1e17f1,0x270e32a624ce5105, | |
0x03a089b9cf427251,0x468ff8821f5007cd,0xf3f13de46ea0de52,0x2353e2eb32dd119c, | |
0x5deef337d58f8050,0x4627b46ab323ee76,0x6bc50f6c85bf5ee4,0x4e85d72c7ad96e41, | |
0xb3a3842fd79e9b66,0xc1b355c2514cc12b,0x4d8d8e57e20a533f,0x9a230f94a80cc9cc, | |
0x20287e80ba5f6a99,0xbf798e5356d5544d,0xa4b98b8f7cf5d947,0x5dfec4b0cf53d480, | |
0xaff6108433392823,0xc77e7eafb9c35034,0x627f1e008407d3a4,0xd8187da069398c24, | |
0x5b82e2951399fb6b,0x8f4165a5b13ef5e5,0xccc6836e6da90f20,0x5bc18466d41ea4b4, | |
0xae57d5f0e7469301,0x382ec77f6dda7973,0x3334a04bfaf89130,0x560ae692d459495d, | |
0xad396981b2cc54c6,0x721ee73a08477f9d,0xac3af4d5f2b948ae,0x8f027b0998907e6a, | |
0xa2aa2576933135d2,0xf977e97a32d0ff40,0xc9ec4b2937331421,0x0a60651dd255075e, | |
0xbc57a87285ad8ce8,0x05f745bb0f2f26c5,0xdbcb6ea37829349e,0xac85ec736c6c05f0, | |
0xa0b8478607780956,0xe1a6cfc18a52c5cf,0xfdc0c9870db192cb,0x6fef6fa94de1275f, | |
0xe7095cf3a87858df,0xa9382116dc12addf,0xfe43770e8ee1fdd0,0x12b5911c68f5a4fa, | |
0xf674859107a9946e,0xbcbcec98535a2e90,0x487bbba9ec45c860,0xa6690ca5bfae55ef, | |
0x2e90b70e4a6edd45,0xf75f315df85c92de,0x73c4b5d3f00c8ff6,0x16e7c2df5e0cc2fd, | |
0x4d3450b5d1238d73,0x3be2360b8e8b5abf,0xaa9f15256af3545e,0x0b78b50380d558f5, | |
0x35b1cd715c1a79c2,0xa5fd04e9b573386e,0xe8287684ad00498d,0x3af5a5175be12d85, | |
0x00bad43e22f3efd0,0x2424d7c00ce3eea8,0x43be6edf2c578cf0,0x4640b84a827945fc, | |
0x7e85782d5ed0fb6d,0xffde4449d800463d,0x5505de67825caf7c,0x958bad14a0d2bebd, | |
0x19031376b81730d2,0xffe7c1cfd5aaf333,0x4a7cd21c4d61a00c,0xd955c74fee9622b4, | |
0xdb600428f8ec65bd,0x412e30c19e4e9b47,0x1b39e37cd46c51fc,0x0b328354c1031b99, | |
0x71eb9da5c27e6be7,0x56dd31a71467973d,0x9cefe510b69e8058,0x516e50ccb614f4a3, | |
0x2feb109a1269f007,0x5bed5039f264362c,0x5a35a81fc188b664,0x86da46de6967b611, | |
0x21cbe3aa2bf1e587,0x814748b95e35060d,0x4532a469e90aafc3,0xe7cdfd61261c5f5f, | |
0x5f9ed3b7b2f0e4c7,0x8633484a1fe91578,0x07982616ddb26917,0x0a4a8fa267fd8e35, | |
0x0169aa3ddb17bbe0,0x7ad23781004a8abb,0x8a99977154276184,0xf5aa49eb805db993, | |
0xa91402c443f56747,0x3a158fd200401788,0x90d1286159a88e33,0x225ba3c00271a613, | |
0xee87820cfe2bc5c1,0xf9cdfc0003d47859,0x58c3aeb0ed7bd81b,0x9dd2e17302417c1c, | |
0x83236763812fd272,0x66337800026dd3d8,0x67926c64cdb2e951,0x28cd00001a9deeb6, | |
0x7f5198092527e597,0x87de18001de39c2a,0x2389f07669962eee,0x4f2800002f2e26ac], dtype=np.uint64) | |
def left_rotate(n, bits): | |
n = np.uint64(n) | |
bits = np.uint64(bits) | |
left = np.left_shift(n, bits) | |
right = np.right_shift(n, (np.uint64(64) - bits)) | |
value = np.bitwise_or(left, right) | |
return np.bitwise_and(value, np.uint64(0xFFFFFFFFFFFFFFFF)) | |
def right_rotate(n, bits): | |
n = np.uint64(n) | |
bits = np.uint64(bits) | |
left = np.right_shift(n, bits) | |
right = np.left_shift(n, (np.uint64(64) - bits)) | |
value = np.bitwise_or(left, right) | |
return np.bitwise_and(value, np.uint64(0xFFFFFFFFFFFFFFFF)) | |
class XorConstantRotation: | |
def __init__(self, seed=np.uint64(1)): | |
self.x = np.uint64(0) | |
self.y = np.uint64(0) | |
self.state = np.uint64(seed) | |
def __call__(self, round): | |
round = np.uint64(round) | |
self.y = (self.x ^ left_rotate(self.state, 32)) ^ left_rotate(self.state, 19) | |
if self.x == 0: | |
self.x = ROUND_CONSTANT[np.mod(round, np.uint64(ROUND_CONSTANT.size))] | |
else: | |
self.x = self.x + (left_rotate(self.x, 7) ^ ROUND_CONSTANT[np.mod(round, np.uint64(ROUND_CONSTANT.size))]) ^ round | |
self.state = (self.state + (self.x ^ self.y)) | |
return self.y | |
def seed(self, seed): | |
self.x = np.uint64(0) | |
self.y = np.uint64(0) | |
self.state = np.uint64(seed) | |
def change_condition(self, value): | |
self.x = np.uint64(value) | |
self.y = np.uint64(0) | |
def main(): | |
# Initialize the pseudo-random number generator | |
prng = XorConstantRotation() | |
# Stores bit sizes and Hamming weights for all constants | |
constant_stats = [] | |
# Test bit sizes and Hamming weights for all constants | |
for constant in ROUND_CONSTANT: | |
bit_size = 64 | |
hamming_weight = bin(constant).count('1') | |
constant_stats.append((bit_size, hamming_weight)) | |
print(f"Constant: {constant}, Bit Size: {bit_size}, Hamming Weight: {hamming_weight}") | |
# Generating 300 64 bits and checking Hamming weights using a pseudo-random number generator | |
generated_numbers = [prng(round) for round in range(1, 301)] | |
generated_stats = [] | |
for i, num in enumerate(generated_numbers): | |
bit_size = 64 | |
hamming_weight = bin(num).count('1') | |
generated_stats.append((bit_size, hamming_weight)) | |
print(f"Round {i+1}: {num}, Bit Size: {bit_size}, Hamming Weight: {hamming_weight}") | |
# Counting the bit sizes and Hamming weights of all constants | |
total_bit_size_a = sum(bit_size for bit_size, _ in constant_stats) | |
total_hamming_weight_a = sum(hamming_weight for _, hamming_weight in constant_stats) | |
# Count the bit sizes and Hamming weights of all generated numbers | |
total_bit_size_b = sum(bit_size for bit_size, _ in generated_stats) | |
total_hamming_weight_b = sum(hamming_weight for _, hamming_weight in generated_stats) | |
# Printing General Statistics | |
print("\nTotal Constant Stats:") | |
print(f"Total Bit Size: {total_bit_size_a}, Total Hamming Weight: {total_hamming_weight_a}") | |
print("\nTotal Generated Stats:") | |
print(f"Total Bit Size: {total_bit_size_b}, Total Hamming Weight: {total_hamming_weight_b}") | |
total_bits_in_sequence = 64 | |
# Calculate bit size percentage | |
bit_size_percentage_constants = (total_bit_size_a / (total_bits_in_sequence * len(ROUND_CONSTANT))) * 100 | |
bit_size_percentage_generated = (total_bit_size_b / (total_bits_in_sequence * len(generated_numbers))) * 100 | |
# Calculation of percentage of Hamming weights | |
hamming_weight_percentage_constants = (total_hamming_weight_a / total_bit_size_a) * 100 | |
hamming_weight_percentage_generated = (total_hamming_weight_b / total_bit_size_b) * 100 | |
# Print results | |
print(f"\nBit Size Percentage - Constants: {bit_size_percentage_constants:.2f}%") | |
print(f"Hamming Weight Percentage - Constants: {hamming_weight_percentage_constants:.2f}%") | |
print(f"\nBit Size Percentage - Generated: {bit_size_percentage_generated:.2f}%") | |
print(f"Hamming Weight Percentage - Generated: {hamming_weight_percentage_generated:.2f}%") | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import warnings | |
import time | |
warnings.filterwarnings("ignore", category=RuntimeWarning) | |
ROUND_CONSTANT = np.array([#Concatenation of Fibonacci numbers., π, φ, e | |
0x01B70C8E97AD5F98,0x243F6A8885A308D3,0x9E3779B97F4A7C15,0xB7E151628AED2A6A, | |
#x ∈ [1, 138] | |
#f(x) = (e^x - cos(πx)) * (φx^2 - φx - 1) * (√2x - floor(√2x)) * (√3 - floor(√3x)) * ln(1+x) * (xδ - floor(xδ)) * (xρ - floor(xρ)) | |
0x6a433d2ae48d4c90,0x9e2b6e6880ad26da,0x5380e7890f281d86,0x47ea9e01d8ef7c3c, | |
0xb7cfc42c4640a591,0x8ba869f86f575f77,0x66ff83fd9954772c,0x0552755b7ef8c3f6, | |
0xe4931d40d079c5cb,0xd6065bf025a81d13,0x586ceb7761d284af,0x5407a44155b8e341, | |
0x7810f48181dff9e2,0x0f44524582d1d6cf,0x919ad67c2cd7118c,0x926d94a3923cb938, | |
0xc3f400bd67479e59,0x83cb03ba7366b70e,0x629043e6e5712e5c,0x69589ff399736efb, | |
0x834d96f80eea56d7,0x02992cb1835476aa,0x78502c2a1b947013,0xbca81dad05eac8c7, | |
0x43216fe770f57c2d,0x604a5ccfe888eef1,0xfcf5bdd0ea8a112c,0xeb13dc4ba7327617, | |
0xf8587cc0dd587813,0x092b98e058140b26,0x1e044153ec902650,0xd13ef3afb71efc3e, | |
0x55af3f5bca28309e,0xcf478054be1173c8,0x99bb2b591f35ac72,0xd3f5e092a0c7c2bb, | |
0xdc120bced1935766,0xbb2525cf28193ea8,0x6a06eb360550e537,0x4501817d5023f9bb, | |
0x6c9e6ef207e06420,0xa12e023656301669,0x2692fa5ed25b6a2b,0xeb48ef08fd6fbdb7, | |
0xfe8db57151c600fb,0x51197bfba60c36ff,0xe95328ef18701542,0x0663e86118debfdd, | |
0xee0b0fcbaf12d0d0,0xc92c72f7a14c35ea,0x21ca0bd30529c74c,0x70243d7854330319, | |
0x193b70b72995d737,0xa936acbbbe88f426,0x61da22530a461898,0x49afa0f477bda24c, | |
0x795bbbc0bf0cdc23,0x3b5f4cf676e0fc41,0xdeec67413dc24105,0x1af46f766498679d, | |
0xa9f37172c15f8e20,0x292b237adf6467a9,0x09538ddc3733c79e,0xde5c2f22b2c1aa42, | |
0x6204c7ebee5a90d8,0x4359ac75de286849,0x7e616650ab318ae8,0xd7552e509ab0d5a6, | |
0xffaf2a408f8cfa95,0x4289e66a0b74427e,0xc5e9869af1856c6d,0x336aa2e2b3dbfeda, | |
0x9835ff10bf4b7e3c,0xc0c5d995789a9c04,0x09dce0a22fccbe60,0x7cc16b5458b38ec9, | |
0x880d6019ab1aa3fa,0xb9ac43e6d90c89dc,0xe0c876bea28b38be,0xafca75b1c80bc8fa, | |
0xf4e5b08059acb0bd,0x643587ac551f3aa0,0x83fa523817844ac9,0x3e97eca86cc41268, | |
0xd53517b095a47a79,0x418aaab53810d432,0xde9ad8739ba769b7,0x6f53b6fb08b9809c, | |
0xe5d41d82eb6a0d63,0x42137200d3b75b64,0x9ee670cd25143c29,0xdc2b3edf3617c034, | |
0xf5d6d70093472506,0xeaca4e8f7eaa4b68,0x0e7b78a6eca0e67e,0x67db9133f144d92d, | |
0xa2f043bdf0bfc70d,0x679513157c68480e,0xc7359f77d43ecedb,0xa73610dd579db5e8, | |
0xd33f00a73c40b3f4,0x1f6693cdc79f41cf,0x402aba3326ff09e4,0xc2f06d96a33ed417, | |
0x16882cd0ac38796e,0xde2342960e538c6e,0xee16a05c0f946350,0xb76895e14d9f81b0, | |
0x8d8e566bbc5b2b65,0x1b1881ca8831ba3c,0x0fb99dab44900c06,0x51701c39eabb7550, | |
0x98c5cadd4f0446cd,0x12cd6ac42824463f,0x815f799d0d2b6b8d,0xd34bed6a3284fb8f, | |
0x1f4f71425e521345,0x5ec3427cc37ef4b7,0x41ca4c3fbb4ae014,0x4d4a5a8399958a44, | |
0x6f21b526d0c7ee3c,0xe85d52cfba2818c0,0x09d0b2cc4deccc35,0x1b13c064ccec4d2e, | |
0x92b538d3b747c6ac,0x58719d59011b3fae,0xedde21671368f97e,0xfc4dbeff22c77aab, | |
0x66997342600d0997,0x6a173e62da2821d7,0xe657b797f1f23506,0x7052226e4dde4ce0, | |
0xcec9d219091d3713,0x46b20fcd9abd9b13,0x0a8bbb7b077261a8,0x8cf03c3c366533db, | |
0x9d167cec4a7f4953,0xed8bbf927c48dbf9,0x21e8d4a1dd84e782,0x4ac104ee6fa65e69, | |
0x5cb955963da25bee,0xa0f791f755ed9ead,0x1125fa77491b7c6a,0x3c0560dc8d08a6b6, | |
0x20cb39c7b8690d0c,0x29a3a26ccc8540de,0x3ba44a4cbb906982,0xddf9454bc0acb110, | |
0xa989a47d915cc360,0xb90af4a05b78e702,0x7f20b78fb8d8eae8,0xedb6cb8180b81603, | |
0xdfe86decf8f940b5,0x4c6baf1de449fc4d,0x165f86d08961df51,0x4c038e6a96040825, | |
0xf4f2cb95b6276944,0xe7f98f0aae90ff54,0xd90fc39cae09f82e,0x45ef9b03350e102c, | |
0xba319140b8a35152,0xa1c8bf3071254d17,0x6d942b49712b2ff0,0x687ab4e1a35f3a7f, | |
0x8fa2a50edfdfce2d,0x1b123d5c5ba08e5b,0x287209f7e4ad4cd4,0xaae61796f1414dd9, | |
0xabd88a4167ec1728,0x584654213d59d9ac,0x1010e8491f4e2d7d,0x01b6087b68d105e5, | |
0xd478306668f2aed3,0x35b78cf5c30272db,0x4e9b1bd35706711d,0xfbee714f84a270e5, | |
0x8855b3fe8d108055,0x1829c0415ef92080,0x2a6238b05b1e17f1,0x270e32a624ce5105, | |
0x03a089b9cf427251,0x468ff8821f5007cd,0xf3f13de46ea0de52,0x2353e2eb32dd119c, | |
0x5deef337d58f8050,0x4627b46ab323ee76,0x6bc50f6c85bf5ee4,0x4e85d72c7ad96e41, | |
0xb3a3842fd79e9b66,0xc1b355c2514cc12b,0x4d8d8e57e20a533f,0x9a230f94a80cc9cc, | |
0x20287e80ba5f6a99,0xbf798e5356d5544d,0xa4b98b8f7cf5d947,0x5dfec4b0cf53d480, | |
0xaff6108433392823,0xc77e7eafb9c35034,0x627f1e008407d3a4,0xd8187da069398c24, | |
0x5b82e2951399fb6b,0x8f4165a5b13ef5e5,0xccc6836e6da90f20,0x5bc18466d41ea4b4, | |
0xae57d5f0e7469301,0x382ec77f6dda7973,0x3334a04bfaf89130,0x560ae692d459495d, | |
0xad396981b2cc54c6,0x721ee73a08477f9d,0xac3af4d5f2b948ae,0x8f027b0998907e6a, | |
0xa2aa2576933135d2,0xf977e97a32d0ff40,0xc9ec4b2937331421,0x0a60651dd255075e, | |
0xbc57a87285ad8ce8,0x05f745bb0f2f26c5,0xdbcb6ea37829349e,0xac85ec736c6c05f0, | |
0xa0b8478607780956,0xe1a6cfc18a52c5cf,0xfdc0c9870db192cb,0x6fef6fa94de1275f, | |
0xe7095cf3a87858df,0xa9382116dc12addf,0xfe43770e8ee1fdd0,0x12b5911c68f5a4fa, | |
0xf674859107a9946e,0xbcbcec98535a2e90,0x487bbba9ec45c860,0xa6690ca5bfae55ef, | |
0x2e90b70e4a6edd45,0xf75f315df85c92de,0x73c4b5d3f00c8ff6,0x16e7c2df5e0cc2fd, | |
0x4d3450b5d1238d73,0x3be2360b8e8b5abf,0xaa9f15256af3545e,0x0b78b50380d558f5, | |
0x35b1cd715c1a79c2,0xa5fd04e9b573386e,0xe8287684ad00498d,0x3af5a5175be12d85, | |
0x00bad43e22f3efd0,0x2424d7c00ce3eea8,0x43be6edf2c578cf0,0x4640b84a827945fc, | |
0x7e85782d5ed0fb6d,0xffde4449d800463d,0x5505de67825caf7c,0x958bad14a0d2bebd, | |
0x19031376b81730d2,0xffe7c1cfd5aaf333,0x4a7cd21c4d61a00c,0xd955c74fee9622b4, | |
0xdb600428f8ec65bd,0x412e30c19e4e9b47,0x1b39e37cd46c51fc,0x0b328354c1031b99, | |
0x71eb9da5c27e6be7,0x56dd31a71467973d,0x9cefe510b69e8058,0x516e50ccb614f4a3, | |
0x2feb109a1269f007,0x5bed5039f264362c,0x5a35a81fc188b664,0x86da46de6967b611, | |
0x21cbe3aa2bf1e587,0x814748b95e35060d,0x4532a469e90aafc3,0xe7cdfd61261c5f5f, | |
0x5f9ed3b7b2f0e4c7,0x8633484a1fe91578,0x07982616ddb26917,0x0a4a8fa267fd8e35, | |
0x0169aa3ddb17bbe0,0x7ad23781004a8abb,0x8a99977154276184,0xf5aa49eb805db993, | |
0xa91402c443f56747,0x3a158fd200401788,0x90d1286159a88e33,0x225ba3c00271a613, | |
0xee87820cfe2bc5c1,0xf9cdfc0003d47859,0x58c3aeb0ed7bd81b,0x9dd2e17302417c1c, | |
0x83236763812fd272,0x66337800026dd3d8,0x67926c64cdb2e951,0x28cd00001a9deeb6, | |
0x7f5198092527e597,0x87de18001de39c2a,0x2389f07669962eee,0x4f2800002f2e26ac], dtype=np.uint64) | |
def left_rotate(n, bits): | |
n = np.uint64(n) | |
bits = np.uint64(bits) | |
left = np.left_shift(n, bits) | |
right = np.right_shift(n, (np.uint64(64) - bits)) | |
value = np.bitwise_or(left, right) | |
return np.bitwise_and(value, np.uint64(0xFFFFFFFFFFFFFFFF)) | |
def right_rotate(n, bits): | |
n = np.uint64(n) | |
bits = np.uint64(bits) | |
left = np.right_shift(n, bits) | |
right = np.left_shift(n, (np.uint64(64) - bits)) | |
value = np.bitwise_or(left, right) | |
return np.bitwise_and(value, np.uint64(0xFFFFFFFFFFFFFFFF)) | |
class XorConstantRotation: | |
def __init__(self, seed=np.uint64(1)): | |
self.x = np.uint64(0) | |
self.y = np.uint64(0) | |
self.state = np.uint64(seed) | |
def __call__(self, round): | |
round = np.uint64(round) | |
self.y = (self.x ^ left_rotate(self.state, 32)) ^ left_rotate(self.state, 19) | |
if self.x == 0: | |
self.x = ROUND_CONSTANT[np.mod(round, np.uint64(ROUND_CONSTANT.size))] | |
else: | |
self.x = self.x + (left_rotate(self.x, 7) ^ ROUND_CONSTANT[np.mod(round, np.uint64(ROUND_CONSTANT.size))]) ^ round | |
self.state = (self.state + (self.x ^ self.y)) | |
return self.y | |
def seed(self, seed): | |
self.x = np.uint64(0) | |
self.y = np.uint64(0) | |
self.state = np.uint64(seed) | |
def change_condition(self, value): | |
self.x = np.uint64(value) | |
self.y = np.uint64(0) | |
class LittleOaldresPuzzle_Cryptic: | |
class KeyState: | |
def __init__(self, subkey, choice_function, bit_rotation_amount_a, bit_rotation_amount_b): | |
self.subkey = subkey | |
self.choice_function = choice_function | |
self.bit_rotation_amount_a = bit_rotation_amount_a | |
self.bit_rotation_amount_b = bit_rotation_amount_b | |
def __init__(self, seed=1, rounds=4): | |
self.seed = seed | |
self.rounds = rounds | |
self.prng = XorConstantRotation(seed) | |
self.key_states = [self.KeyState(0, 0, 0, 0)] * rounds | |
def generate_key_state(self, key_state, number_once, key): | |
# Generate subkey | |
key_state.subkey = key ^ self.prng(number_once) | |
key_state.choice_function = self.prng(key_state.subkey ^ (key >> np.uint64(1))) | |
key_state.bit_rotation_amount_a = self.prng(key_state.subkey ^ key_state.choice_function) | |
# Select bit position 6 ~ 11 | |
key_state.bit_rotation_amount_b = (key_state.bit_rotation_amount_a >> np.uint64(6)) % 64 | |
# Select bit position 0 ~ 5 | |
key_state.bit_rotation_amount_a %= 64 | |
key_state.choice_function %= 4 | |
return key_state | |
def encryption_core_function(self, data, key, number_once): | |
data = np.uint64(data) | |
key = np.uint64(key) | |
number_once = np.uint64(number_once) | |
result = data | |
# Generate and cache key state 生成并缓存密钥状态 | |
for round in range(self.rounds): | |
self.key_states[round] = self.generate_key_state(self.key_states[round], number_once ^ np.uint64(round), key) | |
# Encryption using key states in forward order 正序使用密钥状态进行加密 | |
for key_state in self.key_states: | |
if key_state.choice_function == 0: | |
result ^= key_state.subkey | |
elif key_state.choice_function == 1: | |
result = ~result ^ key_state.subkey | |
elif key_state.choice_function == 2: | |
result = left_rotate(result, key_state.bit_rotation_amount_b) | |
elif key_state.choice_function == 3: | |
result = right_rotate(result, key_state.bit_rotation_amount_b) | |
result ^= (np.uint64(1) << np.uint64(key_state.bit_rotation_amount_a % 64)) | |
result += (right_rotate(key, 3) ^ right_rotate(key_state.subkey, 11)) | |
return result | |
def decryption_core_function(self, data, key, number_once): | |
data = np.uint64(data) | |
key = np.uint64(key) | |
number_once = np.uint64(number_once) | |
result = data | |
# Generate and cache key state 生成并缓存密钥状态 | |
for round in range(self.rounds): | |
self.key_states[round] = self.generate_key_state(self.key_states[round], number_once ^ np.uint64(round), key) | |
# Decryption using key states in backward order 反序使用密钥状态进行解密 | |
for key_state in reversed(self.key_states): | |
result -= (right_rotate(key, 3) ^ right_rotate(key_state.subkey, 11)) | |
result ^= (np.uint64(1) << np.uint64(key_state.bit_rotation_amount_a % 64)) | |
if key_state.choice_function == 0: | |
result ^= key_state.subkey | |
elif key_state.choice_function == 1: | |
result = ~result ^ key_state.subkey | |
elif key_state.choice_function == 2: | |
result = right_rotate(result, key_state.bit_rotation_amount_b) | |
elif key_state.choice_function == 3: | |
result = left_rotate(result, key_state.bit_rotation_amount_b) | |
return result | |
def reset_prng(self): | |
self.prng.seed(self.seed) | |
def test_XorConstantRotation(): | |
csprng = XorConstantRotation() | |
print("CSPRNG 1 (default seed is 1):") | |
for i in range(10): | |
print(f"Round {i}: {csprng(i)}") | |
csprng.seed(1234) | |
for i in range(10): | |
print(f"Round {i}: {csprng(i)}") | |
def single_round_test(): | |
A = np.uint64(1475) | |
B = np.uint64(3695) | |
KeyA = np.uint64(7532) | |
KeyB = np.uint64(9512) | |
seed = np.uint64(1) | |
little_opc = LittleOaldresPuzzle_Cryptic(seed) | |
print("--------------------------------------------------") | |
C = little_opc.encryption_core_function(A, KeyA, np.uint64(1)) | |
D = little_opc.encryption_core_function(B, KeyB, np.uint64(2)) | |
print("A' =", C) | |
print("B' =", D) | |
#!!!!!!!!!!!!!!!!!!!!!! | |
little_opc.reset_prng() | |
C = little_opc.decryption_core_function(C, KeyA, np.uint64(1)) | |
D = little_opc.decryption_core_function(D, KeyB, np.uint64(2)) | |
print("A =", C) | |
print("B =", D) | |
if A == C and B == D: | |
print("The decryption was successful.") | |
else: | |
print("The decryption failed.") | |
print("--------------------------------------------------") | |
def multiple_rounds_test(): | |
data = np.array([1475, 3695, 1258, 7593], dtype=np.uint64) | |
keys = np.array([7532, 9512, 6108, 8729], dtype=np.uint64) | |
encrypted_data = np.zeros_like(data, dtype=np.uint64) | |
decrypted_data = np.zeros_like(data, dtype=np.uint64) | |
seed = np.uint64(1) | |
little_opc = LittleOaldresPuzzle_Cryptic(seed) | |
start_time = time.time() | |
# Encryption | |
for i in range(data.size): | |
encrypted_data[i] = little_opc.encryption_core_function(data[i], keys[i], np.uint64(i)) | |
encryption_duration = int((time.time() - start_time) * 1000) | |
#!!!!!!!!!!!!!!!!!!!!!! | |
little_opc.reset_prng() | |
start_time = time.time() | |
# Decryption | |
for i in range(encrypted_data.size): | |
decrypted_data[i] = little_opc.decryption_core_function(encrypted_data[i], keys[i], np.uint64(i)) | |
decryption_duration = int((time.time() - start_time) * 1000) | |
print("--------------------------------------------------") | |
print("Encryption time:", encryption_duration, "ms") | |
print("Decryption time:", decryption_duration, "ms") | |
print("--------------------------------------------------") | |
print("--------------------------------------------------") | |
# Output | |
for i in range(data.size): | |
print("Original data:", data[i], "Encrypted data:", encrypted_data[i], "Decrypted data:", decrypted_data[i]) | |
if data[i] == decrypted_data[i]: | |
print("Decryption was successful for data", i, ".") | |
else: | |
print("Decryption failed for data", i, ".") | |
print("--------------------------------------------------") | |
def multiple_rounds_with_more_data_test(): | |
data_size = 10 * 1024 * 1024 // 8 # 10 MB of data | |
data = np.random.randint(0, np.iinfo(np.uint64).max, size=data_size, dtype=np.uint64) | |
key_size = 5120 // 8 # 5120-byte keys | |
keys = np.zeros(key_size, dtype=np.uint64) | |
keys[0] = 1 | |
encrypted_data = np.zeros(data_size, dtype=np.uint64) | |
decrypted_data = np.zeros(data_size, dtype=np.uint64) | |
seed = np.uint64(1) | |
little_opc = LittleOaldresPuzzle_Cryptic(seed) | |
start_time = time.time() | |
# Encryption | |
for i in range(data_size): | |
encrypted_data[i] = little_opc.encryption_core_function(data[i], keys[i % key_size], np.uint64(i)) | |
encryption_duration = int((time.time() - start_time) * 1000) | |
#!!!!!!!!!!!!!!!!!!!!!! | |
little_opc.reset_prng() | |
start_time = time.time() | |
# Decryption | |
for i in range(data_size): | |
decrypted_data[i] = little_opc.decryption_core_function(encrypted_data[i], keys[i % key_size], np.uint64(i)) | |
decryption_duration = int((time.time() - start_time) * 1000) | |
print("--------------------------------------------------") | |
print("Encryption time:", encryption_duration, "ms") | |
print("Decryption time:", decryption_duration, "ms") | |
# Output and check for successful decryption | |
num_successful_decrypts = np.sum(data == decrypted_data) | |
print("Number of successful decrypts:", num_successful_decrypts, "out of", data_size) | |
print("--------------------------------------------------") | |
def number_once_counter_mode_test(): | |
A = np.uint64(1475) | |
B = np.uint64(3695) | |
C = np.uint64(0) | |
D = np.uint64(0) | |
KeyA = np.uint64(7532) | |
KeyB = np.uint64(9512) | |
Counter = np.uint64(0) | |
NumberRounds = np.uint64(32) | |
seed = np.uint64(1) | |
little_opc = LittleOaldresPuzzle_Cryptic(seed) | |
print("--------------------------------------------------") | |
# Encryption | |
for round in range(NumberRounds): | |
C ^= little_opc.encryption_core_function(Counter, KeyA, round) | |
D ^= little_opc.encryption_core_function(Counter, KeyB, round) | |
Counter += np.uint64(1) | |
print("A' =", C) | |
print("B' =", D) | |
#!!!!!!!!!!!!!!!!!!!!!! | |
little_opc.reset_prng() | |
Counter = np.uint64(0) | |
# Decryption | |
for round in range(NumberRounds): | |
C ^= little_opc.encryption_core_function(Counter, KeyA, round) | |
D ^= little_opc.encryption_core_function(Counter, KeyB, round) | |
Counter += np.uint64(1) | |
print("A =", C) | |
print("B =", D) | |
print("--------------------------------------------------") | |
number_once_counter_mode_test() | |
test_XorConstantRotation() | |
single_round_test() | |
multiple_rounds_test() | |
multiple_rounds_with_more_data_test() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "XorConstantRotation.hpp" | |
class LittleOaldresPuzzle_Cryptic | |
{ | |
private: | |
std::uint64_t seed = 0; | |
XorConstantRotation prng = XorConstantRotation(seed); | |
std::uint64_t rounds = 4; | |
struct KeyState | |
{ | |
std::uint64_t subkey; | |
std::uint64_t choise_function; | |
std::uint64_t bit_rotation_amount_a; | |
std::uint64_t bit_rotation_amount_b; | |
}; | |
std::vector<KeyState> KeyStates; | |
public: | |
std::uint64_t EncryptionCoreFunction(const std::uint64_t data, const std::uint64_t key, const std::uint64_t number_once) | |
{ | |
std::uint64_t result = data; | |
for(size_t round = 0; round < rounds; round++) | |
{ | |
KeyState key_state = KeyStates[round]; | |
//Generate subkey | |
key_state.subkey = key ^ prng(number_once ^ round); | |
key_state.choise_function = prng(key_state.subkey ^ (key >> 1)); | |
key_state.bit_rotation_amount_a = prng(key_state.subkey ^ key_state.choise_function); | |
//Select bit position 6 ~ 11 | |
key_state.bit_rotation_amount_b = (key_state.bit_rotation_amount_a >> 6) % 64; | |
//Select bit position 0 ~ 5 | |
key_state.bit_rotation_amount_a %= 64; | |
key_state.choise_function %= 4; | |
} | |
for(size_t round = 0; round < rounds; round++) | |
{ | |
KeyState key_state = KeyStates[round]; | |
//Encryption core function | |
switch ( key_state.choise_function ) | |
{ | |
case 0: | |
{ | |
result = result ^ key_state.subkey; | |
break; | |
} | |
case 1: | |
{ | |
result = result ^ key_state.subkey; | |
result = ~result; | |
break; | |
} | |
case 2: | |
{ | |
//2^{6} = 64 | |
result = std::rotl( result, key_state.bit_rotation_amount_b); | |
break; | |
} | |
case 3: | |
{ | |
//2^{6} = 64 | |
result = std::rotr( result, key_state.bit_rotation_amount_b); | |
break; | |
} | |
default: | |
break; | |
} | |
//Non-linear processing - random bit switching | |
//非线性处理 - 随机比特位切换 | |
result ^= ( 1ULL << (key_state.bit_rotation_amount_a % 64) ); | |
result += (std::rotr(key, 3) ^ std::rotr(key_state.subkey, 11)); | |
} | |
return result; | |
} | |
std::uint64_t DecryptionCoreFunction(const std::uint64_t data, const std::uint64_t key, const std::uint64_t number_once) | |
{ | |
std::uint64_t result = data; | |
for(size_t round = 0; round < rounds; round++) | |
{ | |
KeyState key_state = KeyStates[round]; | |
//Generate subkey | |
key_state.subkey = key ^ prng(number_once ^ round); | |
key_state.choise_function = prng(key_state.subkey ^ (key >> 1)); | |
key_state.bit_rotation_amount_a = prng(key_state.subkey ^ key_state.choise_function); | |
//Select bit position 6 ~ 11 | |
key_state.bit_rotation_amount_b = (key_state.bit_rotation_amount_a >> 6) % 64; | |
//Select bit position 0 ~ 5 | |
key_state.bit_rotation_amount_a %= 64; | |
key_state.choise_function %= 4; | |
} | |
for(size_t round = rounds; round > 0; round--) | |
{ | |
KeyState key_state = KeyStates[round - 1]; | |
//Decryption core function | |
result -= (std::rotr(key, 3) ^ std::rotr(key_state.subkey, 11)); | |
//Non-linear processing - random bit switching | |
//非线性处理 - 随机比特位切换 | |
result ^= ( 1ULL << (key_state.bit_rotation_amount_a % 64) ); | |
switch (key_state.choise_function) | |
{ | |
case 0: | |
{ | |
result = result ^ key_state.subkey; | |
break; | |
} | |
case 1: | |
{ | |
result = ~result; | |
result = result ^ key_state.subkey; | |
break; | |
} | |
case 2: | |
{ | |
//2^{6} = 64 | |
result = std::rotr(result, key_state.bit_rotation_amount_b); | |
break; | |
} | |
case 3: | |
{ | |
//2^{6} = 64 | |
result = std::rotl(result, key_state.bit_rotation_amount_b); | |
break; | |
} | |
default: | |
break; | |
} | |
} | |
return result; | |
} | |
void ResetPRNG() | |
{ | |
prng.Seed(seed); | |
} | |
LittleOaldresPuzzle_Cryptic(const std::uint64_t seed, std::uint64_t rounds) | |
: | |
seed(seed), prng(seed), rounds(rounds), KeyStates(std::vector<KeyState>(rounds, KeyState())) | |
{ | |
} | |
LittleOaldresPuzzle_Cryptic(const std::uint64_t seed) | |
: | |
seed(seed), prng(seed), rounds(4), KeyStates(std::vector<KeyState>(rounds, KeyState())) | |
{ | |
} | |
LittleOaldresPuzzle_Cryptic() | |
: | |
seed(1), prng(seed), rounds(4), KeyStates(std::vector<KeyState>(rounds, KeyState())) | |
{ | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <bitset> | |
#include <random> | |
#include <chrono> | |
#include "LittleOaldresPuzzle_Cryptic.hpp" | |
void SingleRoundTest() | |
{ | |
std::uint64_t A = 1475; | |
std::uint64_t B = 3695; | |
std::uint64_t KeyA = 7532; | |
std::uint64_t KeyB = 9512; | |
std::uint64_t seed = 1; | |
LittleOaldresPuzzle_Cryptic LittleOPC(seed); | |
std::cout << "--------------------------------------------------" << std::endl; | |
std::uint64_t C = LittleOPC.EncryptionCoreFunction(A, KeyA, 1); | |
std::uint64_t D = LittleOPC.EncryptionCoreFunction(B, KeyB, 2); | |
std::cout << "A' = " << C << std::endl; | |
std::cout << "B' = " << D << std::endl; | |
LittleOPC.ResetPRNG(); | |
C = LittleOPC.DecryptionCoreFunction(C, KeyA, 1); | |
D = LittleOPC.DecryptionCoreFunction(D, KeyB, 2); | |
std::cout << "A = " << C << std::endl; | |
std::cout << "B = " << D << std::endl; | |
if (A == C && B == D) | |
{ | |
std::cout << "The decryption was successful." << std::endl; | |
} | |
else | |
{ | |
std::cout << "The decryption failed." << std::endl; | |
} | |
std::cout << "--------------------------------------------------" << std::endl; | |
} | |
void MultipleRoundsTest() | |
{ | |
std::vector<std::uint64_t> data = {1475, 3695, 1258, 7593}; | |
std::vector<std::uint64_t> keys = {7532, 9512, 6108, 8729}; | |
std::vector<std::uint64_t> encrypted_data(data.size()); | |
std::vector<std::uint64_t> decrypted_data(data.size()); | |
std::uint64_t seed = 1; | |
LittleOaldresPuzzle_Cryptic LittleOPC(seed); | |
// Encryption | |
for (size_t i = 0; i < data.size(); ++i) | |
{ | |
encrypted_data[i] = LittleOPC.EncryptionCoreFunction(data[i], keys[i], i); | |
} | |
LittleOPC.ResetPRNG(); | |
// Decryption | |
for (size_t i = 0; i < encrypted_data.size(); ++i) | |
{ | |
decrypted_data[i] = LittleOPC.DecryptionCoreFunction(encrypted_data[i], keys[i], i); | |
} | |
std::cout << "--------------------------------------------------" << std::endl; | |
// Output | |
for (size_t i = 0; i < data.size(); ++i) | |
{ | |
std::cout << "Original data: " << data[i] << ", Encrypted data: " << encrypted_data[i] << ", Decrypted data: " << decrypted_data[i] << std::endl; | |
if (data[i] == decrypted_data[i]) | |
{ | |
std::cout << "Decryption was successful for data " << i << "." << std::endl; | |
} | |
else | |
{ | |
std::cout << "Decryption failed for data " << i << "." << std::endl; | |
} | |
} | |
std::cout << "--------------------------------------------------" << std::endl; | |
} | |
void MultipleRoundsWithMoreDataTest() | |
{ | |
std::size_t data_size = 10 * 1024 * 1024 / sizeof(std::uint64_t); // 10 MB of data | |
std::vector<std::uint64_t> data(data_size); | |
std::random_device rd; | |
std::mt19937_64 generator(rd()); | |
std::uniform_int_distribution<std::uint64_t> distribution; | |
// Generate random data | |
for (size_t i = 0; i < data_size; ++i) | |
{ | |
data[i] = distribution(generator); | |
} | |
std::size_t key_size = 5120 / sizeof(std::uint64_t); // 5120-byte keys | |
std::vector<std::uint64_t> keys(key_size, 0); | |
std::vector<std::uint64_t> encrypted_data(data_size); | |
std::vector<std::uint64_t> decrypted_data(data_size); | |
std::uint64_t seed = 1; | |
LittleOaldresPuzzle_Cryptic LittleOPC(seed); | |
auto start_time = std::chrono::high_resolution_clock::now(); | |
// Encryption | |
for (size_t i = 0; i < data.size(); ++i) | |
{ | |
encrypted_data[i] = LittleOPC.EncryptionCoreFunction(data[i], keys[i % key_size], i); | |
} | |
auto end_time = std::chrono::high_resolution_clock::now(); | |
auto encryption_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); | |
LittleOPC.ResetPRNG(); | |
start_time = std::chrono::high_resolution_clock::now(); | |
// Decryption | |
for (size_t i = 0; i < encrypted_data.size(); ++i) | |
{ | |
decrypted_data[i] = LittleOPC.DecryptionCoreFunction(encrypted_data[i], keys[i % key_size], i); | |
} | |
end_time = std::chrono::high_resolution_clock::now(); | |
auto decryption_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count(); | |
std::cout << "--------------------------------------------------" << std::endl; | |
std::cout << "Encryption time: " << encryption_duration << " ms" << std::endl; | |
std::cout << "Decryption time: " << decryption_duration << " ms" << std::endl; | |
// Output and check for successful decryption | |
size_t num_successful_decrypts = 0; | |
for (size_t i = 0; i < data.size(); ++i) | |
{ | |
if (data[i] == decrypted_data[i]) | |
{ | |
++num_successful_decrypts; | |
} | |
} | |
std::cout << "Number of successful decrypts: " << num_successful_decrypts << " out of " << data.size() << std::endl; | |
std::cout << "--------------------------------------------------" << std::endl; | |
} | |
void NunberOnce_CounterMode_Test() | |
{ | |
std::uint64_t A = 1475; | |
std::uint64_t B = 3695; | |
std::uint64_t C = 0; | |
std::uint64_t D = 0; | |
std::uint64_t KeyA = 7532; | |
std::uint64_t KeyB = 9512; | |
std::uint64_t Counter = 0; | |
std::uint64_t NumberRounds = 32; | |
std::uint64_t seed = 1; | |
LittleOaldresPuzzle_Cryptic LittleOPC(seed); | |
std::cout << "--------------------------------------------------" << std::endl; | |
#if 1 | |
// Encryption | |
for (std::uint64_t round = 0; round < NumberRounds; ++round) | |
{ | |
C ^= LittleOPC.EncryptionCoreFunction(Counter, KeyA, round); | |
D ^= LittleOPC.EncryptionCoreFunction(Counter, KeyB, round); | |
++Counter; | |
} | |
std::cout << "A' = " << C << std::endl; | |
std::cout << "B' = " << D << std::endl; | |
LittleOPC.ResetPRNG(); | |
Counter = 0; | |
// Decryption | |
for (std::uint64_t round = 0; round < NumberRounds; ++round) | |
{ | |
C ^= LittleOPC.EncryptionCoreFunction(Counter, KeyA, round); | |
D ^= LittleOPC.EncryptionCoreFunction(Counter, KeyB, round); | |
++Counter; | |
} | |
std::cout << "A = " << C << std::endl; | |
std::cout << "B = " << D << std::endl; | |
#else | |
// Encryption | |
for (std::uint64_t round = 0; round < NumberRounds; ++round) | |
{ | |
C ^= LittleOPC.DecryptionCoreFunction(Counter, KeyA, round); | |
D ^= LittleOPC.DecryptionCoreFunction(Counter, KeyB, round); | |
++Counter; | |
} | |
std::cout << "A' = " << C << std::endl; | |
std::cout << "B' = " << D << std::endl; | |
LittleOPC.ResetPRNG(); | |
Counter = 0; | |
// Decryption | |
for (std::uint64_t round = 0; round < NumberRounds; ++round) | |
{ | |
C ^= LittleOPC.DecryptionCoreFunction(Counter, KeyA, round); | |
D ^= LittleOPC.DecryptionCoreFunction(Counter, KeyB, round); | |
++Counter; | |
} | |
std::cout << "A = " << C << std::endl; | |
std::cout << "B = " << D << std::endl; | |
#endif | |
std::cout << "--------------------------------------------------" << std::endl; | |
} | |
//Test in https://godbolt.org/z/n33h7T8c4 | |
int main() | |
{ | |
/*single-round*/ | |
SingleRoundTest(); | |
/*multiple-rounds*/ | |
MultipleRoundsTest(); | |
/*multiple-rounds with more data*/ | |
MultipleRoundsWithMoreDataTest(); | |
/*NunberOnce/Counter Mode*/ | |
NunberOnce_CounterMode_Test(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <array> | |
#include <bit> | |
constexpr std::array<std::uint64_t, 300> ROUND_CONSTANT | |
{ | |
//Concatenation of Fibonacci numbers., π, φ, e | |
0x01B70C8E97AD5F98ULL,0x243F6A8885A308D3ULL,0x9E3779B97F4A7C15ULL,0xB7E151628AED2A6AULL, | |
//x ∈ [1, 138] | |
//f(x) = (e^x - cos(πx)) * (φx^2 - φx - 1) * (√2x - floor(√2x)) * (√3x - floor(√3x)) * ln(1+x) * (xδ - floor(xδ)) * (xρ - floor(xρ)) | |
0x6a433d2ae48d4c90ULL,0x9e2b6e6880ad26daULL,0x5380e7890f281d86ULL,0x47ea9e01d8ef7c3cULL, | |
0xb7cfc42c4640a591ULL,0x8ba869f86f575f77ULL,0x66ff83fd9954772cULL,0x0552755b7ef8c3f6ULL, | |
0xe4931d40d079c5cbULL,0xd6065bf025a81d13ULL,0x586ceb7761d284afULL,0x5407a44155b8e341ULL, | |
0x7810f48181dff9e2ULL,0x0f44524582d1d6cfULL,0x919ad67c2cd7118cULL,0x926d94a3923cb938ULL, | |
0xc3f400bd67479e59ULL,0x83cb03ba7366b70eULL,0x629043e6e5712e5cULL,0x69589ff399736efbULL, | |
0x834d96f80eea56d7ULL,0x02992cb1835476aaULL,0x78502c2a1b947013ULL,0xbca81dad05eac8c7ULL, | |
0x43216fe770f57c2dULL,0x604a5ccfe888eef1ULL,0xfcf5bdd0ea8a112cULL,0xeb13dc4ba7327617ULL, | |
0xf8587cc0dd587813ULL,0x092b98e058140b26ULL,0x1e044153ec902650ULL,0xd13ef3afb71efc3eULL, | |
0x55af3f5bca28309eULL,0xcf478054be1173c8ULL,0x99bb2b591f35ac72ULL,0xd3f5e092a0c7c2bbULL, | |
0xdc120bced1935766ULL,0xbb2525cf28193ea8ULL,0x6a06eb360550e537ULL,0x4501817d5023f9bbULL, | |
0x6c9e6ef207e06420ULL,0xa12e023656301669ULL,0x2692fa5ed25b6a2bULL,0xeb48ef08fd6fbdb7ULL, | |
0xfe8db57151c600fbULL,0x51197bfba60c36ffULL,0xe95328ef18701542ULL,0x0663e86118debfddULL, | |
0xee0b0fcbaf12d0d0ULL,0xc92c72f7a14c35eaULL,0x21ca0bd30529c74cULL,0x70243d7854330319ULL, | |
0x193b70b72995d737ULL,0xa936acbbbe88f426ULL,0x61da22530a461898ULL,0x49afa0f477bda24cULL, | |
0x795bbbc0bf0cdc23ULL,0x3b5f4cf676e0fc41ULL,0xdeec67413dc24105ULL,0x1af46f766498679dULL, | |
0xa9f37172c15f8e20ULL,0x292b237adf6467a9ULL,0x09538ddc3733c79eULL,0xde5c2f22b2c1aa42ULL, | |
0x6204c7ebee5a90d8ULL,0x4359ac75de286849ULL,0x7e616650ab318ae8ULL,0xd7552e509ab0d5a6ULL, | |
0xffaf2a408f8cfa95ULL,0x4289e66a0b74427eULL,0xc5e9869af1856c6dULL,0x336aa2e2b3dbfedaULL, | |
0x9835ff10bf4b7e3cULL,0xc0c5d995789a9c04ULL,0x09dce0a22fccbe60ULL,0x7cc16b5458b38ec9ULL, | |
0x880d6019ab1aa3faULL,0xb9ac43e6d90c89dcULL,0xe0c876bea28b38beULL,0xafca75b1c80bc8faULL, | |
0xf4e5b08059acb0bdULL,0x643587ac551f3aa0ULL,0x83fa523817844ac9ULL,0x3e97eca86cc41268ULL, | |
0xd53517b095a47a79ULL,0x418aaab53810d432ULL,0xde9ad8739ba769b7ULL,0x6f53b6fb08b9809cULL, | |
0xe5d41d82eb6a0d63ULL,0x42137200d3b75b64ULL,0x9ee670cd25143c29ULL,0xdc2b3edf3617c034ULL, | |
0xf5d6d70093472506ULL,0xeaca4e8f7eaa4b68ULL,0x0e7b78a6eca0e67eULL,0x67db9133f144d92dULL, | |
0xa2f043bdf0bfc70dULL,0x679513157c68480eULL,0xc7359f77d43ecedbULL,0xa73610dd579db5e8ULL, | |
0xd33f00a73c40b3f4ULL,0x1f6693cdc79f41cfULL,0x402aba3326ff09e4ULL,0xc2f06d96a33ed417ULL, | |
0x16882cd0ac38796eULL,0xde2342960e538c6eULL,0xee16a05c0f946350ULL,0xb76895e14d9f81b0ULL, | |
0x8d8e566bbc5b2b65ULL,0x1b1881ca8831ba3cULL,0x0fb99dab44900c06ULL,0x51701c39eabb7550ULL, | |
0x98c5cadd4f0446cdULL,0x12cd6ac42824463fULL,0x815f799d0d2b6b8dULL,0xd34bed6a3284fb8fULL, | |
0x1f4f71425e521345ULL,0x5ec3427cc37ef4b7ULL,0x41ca4c3fbb4ae014ULL,0x4d4a5a8399958a44ULL, | |
0x6f21b526d0c7ee3cULL,0xe85d52cfba2818c0ULL,0x09d0b2cc4deccc35ULL,0x1b13c064ccec4d2eULL, | |
0x92b538d3b747c6acULL,0x58719d59011b3faeULL,0xedde21671368f97eULL,0xfc4dbeff22c77aabULL, | |
0x66997342600d0997ULL,0x6a173e62da2821d7ULL,0xe657b797f1f23506ULL,0x7052226e4dde4ce0ULL, | |
0xcec9d219091d3713ULL,0x46b20fcd9abd9b13ULL,0x0a8bbb7b077261a8ULL,0x8cf03c3c366533dbULL, | |
0x9d167cec4a7f4953ULL,0xed8bbf927c48dbf9ULL,0x21e8d4a1dd84e782ULL,0x4ac104ee6fa65e69ULL, | |
0x5cb955963da25beeULL,0xa0f791f755ed9eadULL,0x1125fa77491b7c6aULL,0x3c0560dc8d08a6b6ULL, | |
0x20cb39c7b8690d0cULL,0x29a3a26ccc8540deULL,0x3ba44a4cbb906982ULL,0xddf9454bc0acb110ULL, | |
0xa989a47d915cc360ULL,0xb90af4a05b78e702ULL,0x7f20b78fb8d8eae8ULL,0xedb6cb8180b81603ULL, | |
0xdfe86decf8f940b5ULL,0x4c6baf1de449fc4dULL,0x165f86d08961df51ULL,0x4c038e6a96040825ULL, | |
0xf4f2cb95b6276944ULL,0xe7f98f0aae90ff54ULL,0xd90fc39cae09f82eULL,0x45ef9b03350e102cULL, | |
0xba319140b8a35152ULL,0xa1c8bf3071254d17ULL,0x6d942b49712b2ff0ULL,0x687ab4e1a35f3a7fULL, | |
0x8fa2a50edfdfce2dULL,0x1b123d5c5ba08e5bULL,0x287209f7e4ad4cd4ULL,0xaae61796f1414dd9ULL, | |
0xabd88a4167ec1728ULL,0x584654213d59d9acULL,0x1010e8491f4e2d7dULL,0x01b6087b68d105e5ULL, | |
0xd478306668f2aed3ULL,0x35b78cf5c30272dbULL,0x4e9b1bd35706711dULL,0xfbee714f84a270e5ULL, | |
0x8855b3fe8d108055ULL,0x1829c0415ef92080ULL,0x2a6238b05b1e17f1ULL,0x270e32a624ce5105ULL, | |
0x03a089b9cf427251ULL,0x468ff8821f5007cdULL,0xf3f13de46ea0de52ULL,0x2353e2eb32dd119cULL, | |
0x5deef337d58f8050ULL,0x4627b46ab323ee76ULL,0x6bc50f6c85bf5ee4ULL,0x4e85d72c7ad96e41ULL, | |
0xb3a3842fd79e9b66ULL,0xc1b355c2514cc12bULL,0x4d8d8e57e20a533fULL,0x9a230f94a80cc9ccULL, | |
0x20287e80ba5f6a99ULL,0xbf798e5356d5544dULL,0xa4b98b8f7cf5d947ULL,0x5dfec4b0cf53d480ULL, | |
0xaff6108433392823ULL,0xc77e7eafb9c35034ULL,0x627f1e008407d3a4ULL,0xd8187da069398c24ULL, | |
0x5b82e2951399fb6bULL,0x8f4165a5b13ef5e5ULL,0xccc6836e6da90f20ULL,0x5bc18466d41ea4b4ULL, | |
0xae57d5f0e7469301ULL,0x382ec77f6dda7973ULL,0x3334a04bfaf89130ULL,0x560ae692d459495dULL, | |
0xad396981b2cc54c6ULL,0x721ee73a08477f9dULL,0xac3af4d5f2b948aeULL,0x8f027b0998907e6aULL, | |
0xa2aa2576933135d2ULL,0xf977e97a32d0ff40ULL,0xc9ec4b2937331421ULL,0x0a60651dd255075eULL, | |
0xbc57a87285ad8ce8ULL,0x05f745bb0f2f26c5ULL,0xdbcb6ea37829349eULL,0xac85ec736c6c05f0ULL, | |
0xa0b8478607780956ULL,0xe1a6cfc18a52c5cfULL,0xfdc0c9870db192cbULL,0x6fef6fa94de1275fULL, | |
0xe7095cf3a87858dfULL,0xa9382116dc12addfULL,0xfe43770e8ee1fdd0ULL,0x12b5911c68f5a4faULL, | |
0xf674859107a9946eULL,0xbcbcec98535a2e90ULL,0x487bbba9ec45c860ULL,0xa6690ca5bfae55efULL, | |
0x2e90b70e4a6edd45ULL,0xf75f315df85c92deULL,0x73c4b5d3f00c8ff6ULL,0x16e7c2df5e0cc2fdULL, | |
0x4d3450b5d1238d73ULL,0x3be2360b8e8b5abfULL,0xaa9f15256af3545eULL,0x0b78b50380d558f5ULL, | |
0x35b1cd715c1a79c2ULL,0xa5fd04e9b573386eULL,0xe8287684ad00498dULL,0x3af5a5175be12d85ULL, | |
0x00bad43e22f3efd0ULL,0x2424d7c00ce3eea8ULL,0x43be6edf2c578cf0ULL,0x4640b84a827945fcULL, | |
0x7e85782d5ed0fb6dULL,0xffde4449d800463dULL,0x5505de67825caf7cULL,0x958bad14a0d2bebdULL, | |
0x19031376b81730d2ULL,0xffe7c1cfd5aaf333ULL,0x4a7cd21c4d61a00cULL,0xd955c74fee9622b4ULL, | |
0xdb600428f8ec65bdULL,0x412e30c19e4e9b47ULL,0x1b39e37cd46c51fcULL,0x0b328354c1031b99ULL, | |
0x71eb9da5c27e6be7ULL,0x56dd31a71467973dULL,0x9cefe510b69e8058ULL,0x516e50ccb614f4a3ULL, | |
0x2feb109a1269f007ULL,0x5bed5039f264362cULL,0x5a35a81fc188b664ULL,0x86da46de6967b611ULL, | |
0x21cbe3aa2bf1e587ULL,0x814748b95e35060dULL,0x4532a469e90aafc3ULL,0xe7cdfd61261c5f5fULL, | |
0x5f9ed3b7b2f0e4c7ULL,0x8633484a1fe91578ULL,0x07982616ddb26917ULL,0x0a4a8fa267fd8e35ULL, | |
0x0169aa3ddb17bbe0ULL,0x7ad23781004a8abbULL,0x8a99977154276184ULL,0xf5aa49eb805db993ULL, | |
0xa91402c443f56747ULL,0x3a158fd200401788ULL,0x90d1286159a88e33ULL,0x225ba3c00271a613ULL, | |
0xee87820cfe2bc5c1ULL,0xf9cdfc0003d47859ULL,0x58c3aeb0ed7bd81bULL,0x9dd2e17302417c1cULL, | |
0x83236763812fd272ULL,0x66337800026dd3d8ULL,0x67926c64cdb2e951ULL,0x28cd00001a9deeb6ULL, | |
0x7f5198092527e597ULL,0x87de18001de39c2aULL,0x2389f07669962eeeULL,0x4f2800002f2e26acULL, | |
}; | |
class XorConstantRotation | |
{ | |
private: | |
std::uint64_t x = 0; | |
std::uint64_t y = 0; | |
std::uint64_t state = 0; | |
public: | |
std::uint64_t operator()(std::uint64_t number_once) | |
{ | |
y = (x ^ std::rotl(state, 32)) ^ std::rotl(state, 19); | |
if(x == 0) | |
x = ROUND_CONSTANT[round % ROUND_CONSTANT.size()]; | |
else | |
x += std::rotl(x, 7) ^ ROUND_CONSTANT[round % ROUND_CONSTANT.size()] ^ number_once; | |
state = (x ^ y) + state; | |
return y; | |
} | |
void Seed(const std::uint64_t seed) | |
{ | |
x = 0; | |
y = 0; | |
state = seed; | |
} | |
void ChangeCondition(const std::uint64_t value) | |
{ | |
x = value; | |
y = 0; | |
} | |
XorConstantRotation() | |
: | |
x(0), y(0), state(1) | |
{ | |
} | |
explicit XorConstantRotation(const std::uint64_t seed) | |
: | |
x(0), y(0), state(seed) | |
{ | |
} | |
XorConstantRotation(const XorConstantRotation& other) = default; | |
XorConstantRotation(XorConstantRotation&& other) = default; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment