├── .gitignore ├── I wrote my own encryption algorithm_!.pdf ├── LICENSE ├── Makefile ├── Makefile.testimage ├── README.md ├── oceantoo.c ├── oceantoo.h ├── sha256.c └── sha256.h /.gitignore: -------------------------------------------------------------------------------- 1 | oceantoo 2 | *.o 3 | -------------------------------------------------------------------------------- /I wrote my own encryption algorithm_!.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garyexplains/oceantoo/f466fb148713e5b04750d79a1b34163a25f6b6f0/I wrote my own encryption algorithm_!.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Gary Sims 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-O3 -Wall 3 | 4 | oceantoo : sha256.o oceantoo.o 5 | $(CC) $(CFLAGS) -o oceantoo sha256.o oceantoo.o 6 | 7 | sha256.o : sha256.c sha256.h 8 | $(CC) $(CFLAGS) -c sha256.c 9 | 10 | oceantoo.o : oceantoo.c oceantoo.h 11 | $(CC) $(CFLAGS) -c oceantoo.c 12 | clean : 13 | rm oceantoo oceantoo.o sha256.o -------------------------------------------------------------------------------- /Makefile.testimage: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021, Dan Drown 2 | # See https://blog.dan.drown.org/cryptanalysis-of-oceantoo/ 3 | 4 | SIZE=400x400 5 | DRAW="rectangle 50,50 350,350; rectangle 100,100 300,300; rectangle 150,150 250,250" 6 | DEPTH=1 7 | 8 | image: example.png example.enc.png 9 | 10 | example.enc.png: example.enc 11 | convert -size $(SIZE) -depth $(DEPTH) gray:example.enc example.enc.png 12 | 13 | example.enc: example.gray 14 | ./oceantoo -p "some random password" example.gray example.enc 15 | 16 | example.png: example.gray 17 | convert -size $(SIZE) -depth $(DEPTH) example.gray example.png 18 | 19 | example.gray: Makefile 20 | convert -size $(SIZE) -depth $(DEPTH) canvas:white -fill none -stroke black -strokewidth 10 -draw $(DRAW) example.gray 21 | 22 | clean: 23 | rm -f example.enc example.enc.png example.gray example.png 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oceantoo 2 | Oceantoo is an XOR/LFSR based encryption algorithm 3 | 4 | ## What is an LFSR? 5 | 6 | A linear-feedback shift register (LFSR) is a method of manipulating a number (a register) by shifting it (moving all the bits to the left or right) and then adding a new bit in the space that was created (the feedback). 7 | 8 | They are often used as pseudo-random numbers generators (as in this case). 9 | 10 | The initial state is called the seed, and because an LFSR is deterministic it will always generate the same number sequence when starting from a given initial state. 11 | 12 | The feedback works by taking certain bits (called taps) and combining them using XOR to generate the bit which will be inserted into the gap created by the sift. 13 | 14 | ### XOR refresher 15 | Exclusive OR is true if, and only if, its arguments differ. So: 16 | 17 | |A|B|XOR| 18 | |-|-|---| 19 | |0|0|0| 20 | |0|1|1| 21 | |1|0|1| 22 | |1|1|0| 23 | 24 | 25 | ### Bit numbering 26 | When reading about LFSRs there can be confusion about how the bits are numbered. 27 | 28 | For example `1011` could be numbered as 29 | 30 | |1|2|3|4| 31 | |-|-|-|-| 32 | |1|0|1|1| 33 | 34 | or as 35 | 36 | |4|3|2|1| 37 | |-|-|-|-| 38 | |1|0|1|1| 39 | 40 | The first method is the traditional way when talking about LFSRs. 41 | 42 | ### 4 bit LFSR 43 | An example of a simple 4 bit LFSR is to use bits 3 and 4. These are combined using XOR and inserted into bit 1, after it has been shifted to the left. 44 | 45 | |1|2|3|4|Notes| 46 | |-|-|-|-|-----| 47 | |1|0|0|1|Bit 3 (0) XOR Bit 4 (1) is 1| 48 | |1|1|0|0| `1001` shifted right is `?100` and then add the carry from above to make `1100`| 49 | |0|1|1|0|| 50 | |1|0|1|1|| 51 | |0|1|0|1|| 52 | |1|0|1|0|| 53 | |1|1|0|1|| 54 | |1|1|1|0|| 55 | |1|1|1|1|Bit 3 (1) XOR Bit 4 (1) is 0| 56 | |0|1|1|1|`1111` shifted right is `?111` and then add the carry from above to make `0111`| 57 | |0|0|1|1|| 58 | |0|0|0|1|| 59 | |1|0|0|0|| 60 | |0|1|0|0|| 61 | |0|0|1|0|| 62 | 63 | When generating random number sequences the bit that is shifted out, that is bit 1, the least significant bit (LSB) is used to generate random bits which are used as random numbers (depending on how many bits are needed). 64 | 65 | ### 128 bit LFSR 66 | Oceantoo uses a 128-bit LFSR with the taps of 128, 127, 126, 121. Such an LFSR has a maximum cycle, meaning it will generate 340,282,366,920,938,463,463,374,607,431,768,211,455 unique numbers, with no repeats!!! 67 | 68 | ### LFSR Weakness 69 | Given a sufficient amount of data there are ways to determine "crack" the LFSR and get its initial state and simulate the numbers it generates. The Berlekamp–Massey algorithm is an algorithm that will find the shortest linear feedback shift register (LFSR) for a given binary output sequence. 70 | 71 | To overcome this weakness there are various methods which can be used. One method is to use a multiplexed LFSR. These were first mentioned in the PhD thesis of S. M. Jennings in 1980. 72 | 73 | Multiplexed LFSRs and Shrinking Generators use multiple LFSRs. In the case of the latter one LFSR controls how the other is used. So if you have LFSR1 and LFSR2, when the LSB of LSFR1 is 1, then the output of the sequence is the LSB of LFSR2. When LFSR1 is 0, the LSB of LFSR2 is discarded. The algorithm then loops, until LFSR1 generates a 1, and so LFSR2 is used. 74 | 75 | Other variations include alternating between LFSR1 and LFSR2, etc. 76 | 77 | ### A note on FISH and PIKE 78 | 79 | FISH (FIbonacci SHrinking) is an encryption algorithm published by Siemens in 1993. According to Ross Anderson showed that FISH can be broken with just a few thousand bits of known plaintext (see On Fibonacci KEystream Generators). 80 | 81 | In the same paper Anderson suggested PIKE. PIKE improves on FISH. Anderson notes that "had the control bits been the carry bits rather than the least significant bits, then our attack would have been much harder". 82 | 83 | Therefore Oceantoo uses the carry bits of an LFSR to shrink the sequence (see below). 84 | 85 | PIKE also used XOR for the LSBs of each LFSR, as does Oceantoo. 86 | 87 | ### Oceantoo's LFSRs 88 | In the paper "Statistical Weaknessof Multiplexed Sequences" Jovan Dj. Golic et al showed that there are some inherent weaknesses in multiplexed LFSRs. The paper also suggested some remedies. Namely to decimate (shrink) the output of the LFSR (similar to the shrinking generator) and to XOR the output of the two LFSRs. 89 | 90 | Oceantoo's uses 3 LFSRS. All 128-bit. 91 | 92 | LFSR3 is used to decimate the output. If the carry bit of LFSR3 is 1 then the LSB of LFSR1 is ignored for 1 bit, while the LSB of LFSR2 is ignored for 2 bits. However the algorithm doesn't loop back around. This is an arbitrary action taken whenever the carry bit of LFSR3 is 1. 93 | 94 | Then the output of the random number sequence generator is LFSR1 XOR LFSR2. 95 | 96 | The idea is that the state of LFSR1 and LFSR2 can't be determined since the sequence is an XOR of the generated bits. Furthermore, LFSR1 and LFSR2 aren't in step since the shrinking of LFSR1 and LFSR2 is different and only occurs when the carry bit of LFSR3 is 1. 97 | 98 | ### Seed 99 | Each LFSR needs an initial state, in fact 128-bits of initial state. Oceantoo initializes the LFSRs by taking a plaintext password and generating a SHA256 hash for the string. The first 128 bits of that hash are used to initialise an LFSR, called the LFSR Captain. The captain is then used as a standard LFSR to generate 3x128bits of data, that are used to initialize LFSR1-3. LFSR Captain is then discarded. For decode, the initial state of the three LFSRs will be the same if the same password is supplied. 100 | 101 | Oceantoo also has the option to move along its sequence by `n` bytes before starting the encode or decode. This means that to encode a file you need to supply a password and an optional offset. To decode you need the same password and the same offset, otherwise decode will fail. 102 | 103 | The use of the offset has the potential to use Oceantoo as a one-time pad (OTP). Every new message that is encrypted needs to start from a new offset, which should be +1 longer than the length of the previously encoded message. One of the conditions for successful OTP is that the key must never be reused in whole or in part. 104 | 105 | ### Encryption 106 | The actual encryption is done using XOR. Each byte of the file is XORed with the next byte out of the three 128-bit LFSR combo. This means that to encrypt a file you run it through Oceantoo once and to decrypt it, you run it through again! 107 | 108 | ### Performance 109 | One of the advantages of a LFSR is that it is easy to implement in hardware. The nature of the shift register setup allows for high performance encryption. The addition of shrinking and the use of multiple LFSRs means Oceantoo is not as efficient as other encryption mechanisms. 110 | 111 | ### Example usage 112 | * `oceantoo -p mypassword1 secret_designs.doc secret_designs.doc.oct` - This will encode the Word document `secret_designs.doc` with the key `mypassword1` and write the output to `secret_designs.doc.oct` 113 | * `oceantoo -p mypassword1 secret_designs.doc.oct secret_designs.doc` - Is the reverse (i.e. decode) of above. 114 | * `oceantoo -p mypassword1 -n 187172 secret_designs.doc secret_designs.doc.oct` - This will encode the Word document `secret_designs.doc` with the key `mypassword1` and offset of 187172 and write the output to `secret_designs.doc.oct` 115 | * `oceantoo -p mypassword1 -n 187172 secret_designs.doc.oct secret_designs.doc` - Is the reverse (i.e. decode) of above. 116 | * `oceantoo -p mypassword1 -n 9854213 -r -l 50` - Will print 50 random bytes (0-255) from the Oceantoo's LFSRs based on the password and offset. 117 | * `oceantoo -1 0x00 -2 0x00 -r -l 10` - Will print 10 random bytes from Oceantoo's LFSRs, which has been forcefully initialized to the bit pattern set by `-1` and `-2` (`lsfr_l` and `lfsr_h` respectively). 118 | * `oceantoo -c -1 0xAAFFEEDDFEFE0000 -2 0xAABBCCFEFE00007E -r -l 10 -v` - Will print 10 random bytes from Oceantoo's LFSRs, where the LFSR Captain has been forcefully initialized to the bit pattern set by `-1` and `-2` (`lsfr_l` and `lfsr_h` respectively). Extra debug info is provided via the `-v` flag. 119 | 120 | ### Disclaimer because good cryptography is hard! 121 | "Anyone can create an algorithm that he himself cannot break" - Bruce Schneier. 122 | 123 | Good cryptography is hard, there are lots of pitfalls, etc. Oceantoo has never been scrutinized by mathematicians or cryptography experts. It should be considered purely an academic (and amateur) project. 124 | 125 | Oceanto is provided "as is" and any express or implied warranties, including, but not limited to, the implied warranties of fitness for a particular purpose are disclaimed. 126 | 127 | YOU HAVE BEEN WARNED. 128 | 129 | ### Acknowledgements 130 | The SHA256 code comes from Brad Conte. See his GitHub here: https://github.com/B-Con/crypto-algorithms 131 | -------------------------------------------------------------------------------- /oceantoo.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021, Gary Sims 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "oceantoo.h" 22 | #include "sha256.h" 23 | 24 | void lfsr128_set_password(lfsr128_t *l, unsigned char *p) { 25 | BYTE buf[SHA256_BLOCK_SIZE]; 26 | SHA256_CTX ctx; 27 | uint64_t lfsr_h; 28 | uint64_t lfsr_l; 29 | 30 | sha256_init(&ctx); 31 | sha256_update(&ctx, p, strlen((char *) p)); 32 | sha256_final(&ctx, buf); 33 | memcpy(&lfsr_h, buf, sizeof(uint64_t)); 34 | memcpy(&lfsr_l, buf + sizeof(uint64_t), sizeof(uint64_t)); 35 | lfsr128_init(l, lfsr_h, lfsr_l); 36 | } 37 | 38 | void lfsr128x3_set_from_captain(lfsr128_t *captain, lfsr128x3_t *l) { 39 | l->lfsr[0].lfsr_h = lfsr128_shiftn(captain, 64); 40 | l->lfsr[0].lfsr_l = lfsr128_shiftn(captain, 64); 41 | l->lfsr[1].lfsr_h = lfsr128_shiftn(captain, 64); 42 | l->lfsr[1].lfsr_l = lfsr128_shiftn(captain, 64); 43 | l->lfsr[2].lfsr_h = lfsr128_shiftn(captain, 64); 44 | l->lfsr[2].lfsr_l = lfsr128_shiftn(captain, 64); 45 | } 46 | 47 | void lfsr128x3_set_password(lfsr128x3_t *l, unsigned char *p) { 48 | lfsr128_t lfsr128_captain; 49 | 50 | lfsr128_set_password(&lfsr128_captain, p); 51 | lfsr128x3_set_from_captain(&lfsr128_captain, l); 52 | } 53 | 54 | void lfsr128x3_set_init_state(lfsr128x3_t *l, lfsr128_t *initState) { 55 | l->lfsr[0].lfsr_h = initState->lfsr_h; 56 | l->lfsr[0].lfsr_l = initState->lfsr_l; 57 | l->lfsr[1].lfsr_h = initState->lfsr_h; 58 | l->lfsr[1].lfsr_l = initState->lfsr_l; 59 | l->lfsr[2].lfsr_h = initState->lfsr_h; 60 | l->lfsr[2].lfsr_l = initState->lfsr_l; 61 | } 62 | 63 | void lfsr128x3_set_cap_state(lfsr128x3_t *l, lfsr128_t *initState) { 64 | lfsr128_t lfsr128_captain; 65 | 66 | lfsr128_init(&lfsr128_captain, initState->lfsr_h, initState->lfsr_l); 67 | lfsr128x3_set_from_captain(&lfsr128_captain, l); 68 | } 69 | 70 | void lfsr128_init(lfsr128_t *l, uint64_t lfsr_h, uint64_t lfsr_l) { 71 | l->lfsr_h = lfsr_h; 72 | l->lfsr_l = lfsr_l; 73 | } 74 | 75 | uint64_t lfsr128_shift(lfsr128_t *l) { 76 | uint64_t bit, bit_h, r; 77 | r = l->lfsr_l & 1; 78 | bit = ((l->lfsr_l >> 0) ^ (l->lfsr_l >> 1) ^ (l->lfsr_l >> 2) ^ 79 | (l->lfsr_l >> 7)) & 1; 80 | bit_h = l->lfsr_h & 1; 81 | l->lfsr_l = (l->lfsr_l >> 1) | (bit_h << 63); 82 | l->lfsr_h = (l->lfsr_h >> 1) | (bit << 63); 83 | 84 | return r; 85 | } 86 | 87 | /* 88 | * Return the carry bit, not the shited out bit 89 | */ 90 | uint64_t lfsr128_shift_return_carry(lfsr128_t *l) { 91 | uint64_t bit, bit_h; 92 | bit = ((l->lfsr_l >> 0) ^ (l->lfsr_l >> 1) ^ (l->lfsr_l >> 2) ^ 93 | (l->lfsr_l >> 7)) & 1; 94 | bit_h = l->lfsr_h & 1; 95 | l->lfsr_l = (l->lfsr_l >> 1) | (bit_h << 63); 96 | l->lfsr_h = (l->lfsr_h >> 1) | (bit << 63); 97 | 98 | return bit; 99 | } 100 | 101 | uint64_t lfsr128_shiftn(lfsr128_t *l, uint8_t n) { 102 | uint64_t r = 0; 103 | int i; 104 | r = lfsr128_shift(l); 105 | for (i = 0; i < n - 1; i++) { 106 | r = r << 1; 107 | r = r | lfsr128_shift(l); 108 | } 109 | 110 | return r; 111 | } 112 | 113 | uint64_t lfsr128_shift_with_mult_dec(lfsr128x3_t *l) { 114 | uint64_t r0, r1, r2; 115 | 116 | r0 = lfsr128_shift(&l->lfsr[0]); 117 | r1 = lfsr128_shift(&l->lfsr[1]); 118 | r2 = lfsr128_shift_return_carry(&l->lfsr[2]); 119 | 120 | if (r2 == 1) { 121 | /* Decimate r0 by 1 bit, r2 by 2 bits*/ 122 | r0 = lfsr128_shift(&l->lfsr[0]); 123 | r1 = lfsr128_shift(&l->lfsr[1]); 124 | r1 = lfsr128_shift(&l->lfsr[1]); 125 | } 126 | 127 | return r0 ^ r1; 128 | } 129 | 130 | uint64_t lfsr128_shiftn_with_mult_dec(lfsr128x3_t *l, uint8_t n) { 131 | uint64_t r = 0; 132 | int i; 133 | 134 | r = lfsr128_shift_with_mult_dec(l); 135 | for (i = 0; i < n - 1; i++) { 136 | r = r << 1; 137 | r = r | lfsr128_shift_with_mult_dec(l); 138 | } 139 | 140 | return r; 141 | } 142 | 143 | void code_buffer(uint8_t *b, lfsr128x3_t *l, int sz) { 144 | for(int i=0;i \n" 162 | "Options: \n" 163 | "\t-p - Password (i.e. key)\n" 164 | "\t-n - Random number seq offset\n" 165 | "\t-r - Print random numbers (doesn't encode/decode the file)\n" 166 | "\t-1 - Testing: Force set lower 64 bits of the 3 LFSRs, in hex\n" 167 | "\t-2 - Testing: Force set upper 64 bits of the 3 LFSRs, in hex\n" 168 | "\t-c - Testing: Force set the captain instead (with -1 and -2)\n" 169 | "Arguments: \n" 170 | "\tsource - Input filename \n" 171 | "\toutput - Output filename \n"); 172 | } 173 | 174 | int main(int argc, char *argv[]) { 175 | 176 | int opt; 177 | int offset = -1; 178 | int verbose = 0; 179 | int print_random_numbers = 0; 180 | unsigned char *password = NULL; 181 | char *input_fn = NULL; 182 | char *output_fn = NULL; 183 | lfsr128x3_t lfsr; 184 | int how_many_rand_nums = 1000000; 185 | int use_init_state = 0; 186 | int init_state_captain = 0; 187 | lfsr128_t init_state = {0,0}; 188 | 189 | while ((opt = getopt(argc, argv, "rl:n:p:hv1:2:c?")) != -1) { 190 | switch (opt) { 191 | case 'v': 192 | verbose = 1; 193 | break; 194 | case 'r': 195 | print_random_numbers = 1; 196 | break; 197 | case 'l': 198 | how_many_rand_nums = atoi(optarg); 199 | break; 200 | case 'n': 201 | offset = atoi(optarg); 202 | break; 203 | case 'p': 204 | password = malloc(strlen(optarg) + 1); 205 | strcpy((char *) password, optarg); 206 | break; 207 | case 'h': 208 | usage(); 209 | exit(EXIT_FAILURE); 210 | break; 211 | case '1': 212 | use_init_state = 1; 213 | init_state.lfsr_l = strtoull(optarg, NULL, 16); 214 | break; 215 | case '2': 216 | use_init_state = 1; 217 | init_state.lfsr_h = strtoull(optarg, NULL, 16); 218 | break; 219 | case 'c': 220 | init_state_captain = 1; 221 | break; 222 | default: /* '?' */ 223 | usage(); 224 | exit(EXIT_FAILURE); 225 | } 226 | } 227 | 228 | if (password == NULL && !use_init_state) { 229 | fprintf(stderr, "Password needed.\n\n"); 230 | usage(); 231 | exit(EXIT_FAILURE); 232 | } 233 | 234 | if (print_random_numbers == 0) { 235 | if (optind >= argc) { 236 | fprintf(stderr, "Expected two arguments after options.\n\n"); 237 | usage(); 238 | exit(EXIT_FAILURE); 239 | } 240 | 241 | if (optind + 1 >= argc) { 242 | fprintf(stderr, "Expected another argument.\n\n"); 243 | usage(); 244 | exit(EXIT_FAILURE); 245 | } 246 | input_fn = malloc(strlen(argv[optind]) + 1); 247 | strcpy(input_fn, argv[optind]); 248 | output_fn = malloc(strlen(argv[optind + 1]) + 1); 249 | strcpy(output_fn, argv[optind + 1]); 250 | } 251 | 252 | if (verbose) { 253 | if (offset > 0) { 254 | printf("Offset (-n): %d\n", offset); 255 | } 256 | 257 | if (password != NULL) { 258 | printf("Password: %s\n", password); 259 | } 260 | if (use_init_state) { 261 | printf( 262 | "Forced initial state of %s: %lx,%lx\n", 263 | init_state_captain ? "captain" : "LFSRs", 264 | init_state.lfsr_h, 265 | init_state.lfsr_l 266 | ); 267 | } 268 | if (print_random_numbers) { 269 | printf("Printing random numbers...\n"); 270 | } else { 271 | printf("Input filename: %s\n", input_fn); 272 | printf("Output filename: %s\n", output_fn); 273 | } 274 | } 275 | 276 | if (use_init_state) { 277 | if (init_state_captain) { 278 | lfsr128x3_set_cap_state(&lfsr, &init_state); 279 | } else { 280 | lfsr128x3_set_init_state(&lfsr, &init_state); 281 | } 282 | } else { 283 | lfsr128x3_set_password(&lfsr, password); 284 | } 285 | 286 | if(offset > 0) { 287 | for(int i=0;i 0) { 317 | code_buffer(buffer, &lfsr, n); 318 | fwrite(buffer, 1, n, fp_out); 319 | } 320 | 321 | fclose(fp_in); 322 | fclose(fp_out); 323 | 324 | return EXIT_SUCCESS; 325 | } 326 | -------------------------------------------------------------------------------- /oceantoo.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021, Gary Sims 2 | * All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | */ 14 | 15 | #ifndef LFSR128_H 16 | #define LFSR128_H 17 | 18 | /*************************** HEADER FILES ***************************/ 19 | #include 20 | 21 | /*************************** DEFINES ***************************/ 22 | #define BUFFER_SZ 4096 23 | 24 | /**************************** DATA TYPES ****************************/ 25 | typedef struct lfsr128_t { 26 | uint64_t lfsr_h; 27 | uint64_t lfsr_l; 28 | } lfsr128_t; 29 | 30 | typedef struct lfsr128x3_t { 31 | lfsr128_t lfsr[3]; 32 | } lfsr128x3_t; 33 | 34 | /*********************** FUNCTION DECLARATIONS **********************/ 35 | 36 | void lfsr128_set_password(lfsr128_t *l, unsigned char *p); 37 | void lfsr128_init(lfsr128_t *l, uint64_t lfsr_h, uint64_t lfsr_l); 38 | uint64_t lfsr128_shift(lfsr128_t *l); 39 | uint64_t lfsr128_shiftn(lfsr128_t *l, uint8_t n); 40 | uint64_t lfsr128_shift_with_mult_dec(lfsr128x3_t *l); 41 | uint64_t lfsr128_shiftn_with_mult_dec(lfsr128x3_t *l, uint8_t n); 42 | uint64_t lfsr128_shift_return_carry(lfsr128_t *l); 43 | void lfsr128x3_set_password(lfsr128x3_t *l, unsigned char *p); 44 | uint64_t lfsr128_shift_with_mult_dec(lfsr128x3_t *l); 45 | void do_print_random_numbers(lfsr128x3_t *l, int sz); 46 | void code_buffer(uint8_t *b, lfsr128x3_t *l, int sz); 47 | 48 | void usage(); 49 | 50 | #endif // LFSR128_H 51 | -------------------------------------------------------------------------------- /sha256.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the SHA-256 hashing algorithm. 7 | SHA-256 is one of the three algorithms in the SHA2 8 | specification. The others, SHA-384 and SHA-512, are not 9 | offered in this implementation. 10 | Algorithm specification can be found here: 11 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 12 | This implementation uses little endian byte order. 13 | *********************************************************************/ 14 | 15 | /*************************** HEADER FILES ***************************/ 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /****************************** MACROS ******************************/ 21 | #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 22 | #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 23 | 24 | #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 25 | #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 26 | #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 27 | #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 28 | #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 29 | #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 30 | 31 | /**************************** VARIABLES *****************************/ 32 | static const WORD k[64] = { 33 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 34 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 35 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 36 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 37 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 38 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 39 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 40 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 41 | }; 42 | 43 | /*********************** FUNCTION DEFINITIONS ***********************/ 44 | void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) 45 | { 46 | WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 47 | 48 | for (i = 0, j = 0; i < 16; ++i, j += 4) 49 | m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 50 | for ( ; i < 64; ++i) 51 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 52 | 53 | a = ctx->state[0]; 54 | b = ctx->state[1]; 55 | c = ctx->state[2]; 56 | d = ctx->state[3]; 57 | e = ctx->state[4]; 58 | f = ctx->state[5]; 59 | g = ctx->state[6]; 60 | h = ctx->state[7]; 61 | 62 | for (i = 0; i < 64; ++i) { 63 | t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 64 | t2 = EP0(a) + MAJ(a,b,c); 65 | h = g; 66 | g = f; 67 | f = e; 68 | e = d + t1; 69 | d = c; 70 | c = b; 71 | b = a; 72 | a = t1 + t2; 73 | } 74 | 75 | ctx->state[0] += a; 76 | ctx->state[1] += b; 77 | ctx->state[2] += c; 78 | ctx->state[3] += d; 79 | ctx->state[4] += e; 80 | ctx->state[5] += f; 81 | ctx->state[6] += g; 82 | ctx->state[7] += h; 83 | } 84 | 85 | void sha256_init(SHA256_CTX *ctx) 86 | { 87 | ctx->datalen = 0; 88 | ctx->bitlen = 0; 89 | ctx->state[0] = 0x6a09e667; 90 | ctx->state[1] = 0xbb67ae85; 91 | ctx->state[2] = 0x3c6ef372; 92 | ctx->state[3] = 0xa54ff53a; 93 | ctx->state[4] = 0x510e527f; 94 | ctx->state[5] = 0x9b05688c; 95 | ctx->state[6] = 0x1f83d9ab; 96 | ctx->state[7] = 0x5be0cd19; 97 | } 98 | 99 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) 100 | { 101 | WORD i; 102 | 103 | for (i = 0; i < len; ++i) { 104 | ctx->data[ctx->datalen] = data[i]; 105 | ctx->datalen++; 106 | if (ctx->datalen == 64) { 107 | sha256_transform(ctx, ctx->data); 108 | ctx->bitlen += 512; 109 | ctx->datalen = 0; 110 | } 111 | } 112 | } 113 | 114 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]) 115 | { 116 | WORD i; 117 | 118 | i = ctx->datalen; 119 | 120 | // Pad whatever data is left in the buffer. 121 | if (ctx->datalen < 56) { 122 | ctx->data[i++] = 0x80; 123 | while (i < 56) 124 | ctx->data[i++] = 0x00; 125 | } 126 | else { 127 | ctx->data[i++] = 0x80; 128 | while (i < 64) 129 | ctx->data[i++] = 0x00; 130 | sha256_transform(ctx, ctx->data); 131 | memset(ctx->data, 0, 56); 132 | } 133 | 134 | // Append to the padding the total message's length in bits and transform. 135 | ctx->bitlen += ctx->datalen * 8; 136 | ctx->data[63] = ctx->bitlen; 137 | ctx->data[62] = ctx->bitlen >> 8; 138 | ctx->data[61] = ctx->bitlen >> 16; 139 | ctx->data[60] = ctx->bitlen >> 24; 140 | ctx->data[59] = ctx->bitlen >> 32; 141 | ctx->data[58] = ctx->bitlen >> 40; 142 | ctx->data[57] = ctx->bitlen >> 48; 143 | ctx->data[56] = ctx->bitlen >> 56; 144 | sha256_transform(ctx, ctx->data); 145 | 146 | // Since this implementation uses little endian byte ordering and SHA uses big endian, 147 | // reverse all the bytes when copying the final state to the output hash. 148 | for (i = 0; i < 4; ++i) { 149 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 150 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 151 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 152 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 153 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 154 | hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 155 | hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 156 | hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /sha256.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding SHA1 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef SHA256_H 10 | #define SHA256_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | #include 15 | 16 | /****************************** MACROS ******************************/ 17 | #define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest 18 | 19 | /**************************** DATA TYPES ****************************/ 20 | typedef uint8_t BYTE; // 8-bit byte 21 | typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines 22 | 23 | typedef struct { 24 | BYTE data[64]; 25 | WORD datalen; 26 | uint64_t bitlen; 27 | WORD state[8]; 28 | } SHA256_CTX; 29 | 30 | /*********************** FUNCTION DECLARATIONS **********************/ 31 | void sha256_init(SHA256_CTX *ctx); 32 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); 33 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]); 34 | 35 | #endif // SHA256_H 36 | --------------------------------------------------------------------------------