Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Twilight-Dream-Of-Magic/d269786a59a53f60ab79797cd84f268a to your computer and use it in GitHub Desktop.
Save Twilight-Dream-Of-Magic/d269786a59a53f60ab79797cd84f268a to your computer and use it in GitHub Desktop.
LittleOaldresPuzzle_Cryptic StreamCipher
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()
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()
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()
#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()))
{
}
};
#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;
}
#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