# Codebreakers and Codewriters

Let's say you have some text, and you want it to send it to your friend, but you don't want anyone else to read it. That probably means you want to encrypt it so that only you and your friend can read it. But, there is a problem: you and your friend forgot to agree on an encryption method, so if you send them a message, they won't be able to decrypt it!

After thinking about this for a while, you decide to just send your friend the code to encrypt your message along with the message. Your friend is very smart, so they can probably figure out how to decrypt the message by studying the encryption method.

Of course, since other people might be reading the message, you want to choose an encryption scheme that makes it as hard as possible to crack (figure out the decryption scheme).

In this challenge, Cops will play the role of the writer: you will design an encryption scheme that converts strings to strings. However, this encryption scheme must be bijective, meaning that no two strings must map to another string, and every string can be mapped to by an input. It must take only one input—the string to be encoded.

You will then post some code that performs the encryption, and a single message encrypted with the scheme detailed by your code.

Since you are paying by the byte to send messages, your score will be the length of your code plus the length of the ciphertext. If your answer is cracked, you will have a score of infinity.

After one week, you may reveal the text and mark your answer as Safe. Safe answers are those that cannot be cracked.

Robbers will play either as the friend of the writer or the malicious middle man (there is no material difference, but you can role-play as either if it makes it more fun to do so). They will take the encryption schemes and the ciphertext and attempt to figure out the encrypted message. Once they figure out the encrypted message, they will post it in a comment. (There will not be a separate robbers' thread for this question.)

The winner will be the robber with the most cracks.

Here is an example of what a cracked solution might look like:

• If the encoding is bijective, what are the domain and codomain? – Leaky Nun Jul 19 '17 at 18:21
• The strings with which characters? – Leaky Nun Jul 19 '17 at 18:22
• @WheatWizard Which 256? You mean 256 bytes not characters right? – Erik the Outgolfer Jul 19 '17 at 18:34
• What's to stop somebody from using a cryptographically secure function? – Tutleman Jul 19 '17 at 18:49
• On who is the burden of proving bijectivity: the cop or potential robbers? I.e., if it is unknown if a function is bijective, what happens? – Stephen Jul 19 '17 at 19:28

# Jelly, 57 + 32 = 89 bytes (cracked)

“¡ḟċ⁷Ḣṡ⁵ĊnɠñḂƇLƒg⁺QfȥẒṾ⁹+=?JṚWġ%Aȧ’
O‘ḅ256b¢*21%¢ḅ¢ḃ256’Ọ


Encrypted message:

EªæBsÊ$Ê³¢?r×­Q4e²?ò[Ý6  As a hex-string: 4518AAE6421973CA 9724CAB3A23F72D7 AD18855134651810 B23F1CF25BDD9036  Explanation: O‘ḅ256b¢*21%¢ḅ¢ḃ256’Ọ O convert each into codepoint ‘ḅ256 convert from bijective base 256 to integer b¢ convert from integer to base N *21 map each to its 21th power %¢ modulo N ḅ¢ convert to integer from base N ḃ256’ convert from integer to bijective base 256 Ọ convert each from codepoint  Where N is encoded by the string “¡ḟċ⁷Ḣṡ⁵ĊnɠñḂƇLƒg⁺QfȥẒṾ⁹+=?JṚWġ%Aȧ’, which is the number 105587021056759938494595233483151378724567978408381355454441180598980268016731. Also, this is the RSA method with N given above and public key 21. Cracking this is equivalent to finding the two prime factors of N. • Well. I'm able to decrypt my own encrypted message with the key I've found, but it seems to fail with yours. :-/ (The expected result is not a 4-character non-English message, is it?) – Arnauld Jul 19 '17 at 22:18 • The message is _ìNb (Try it online!). – Anders Kaseorg Jul 19 '17 at 22:23 • @AndersKaseorg Yup. That's what I had, but I was expecting something slightly more meaningful. :-) – Arnauld Jul 19 '17 at 22:25 • For what it's worth, here is the code I used on my side. – Arnauld Jul 19 '17 at 22:42 • @AndersKaseorg Jelly attempts to eval it's arguments, so null bytes are indeed possible. tio.run/##y0rNyan8/9//////6jEGIKgOAA – Dennis Jul 20 '17 at 5:43 # Jelly, 88 + 64 = 152 bytes Encryption function: “¥@ɦ⁺€€ṄyȤDƁWĊ;Y^y⁻U ⁸ßɠƁXẹṡWZc'µ÷ḷỊ0ÇtṙA×Ḃß4©qV)iḷỊDƭ Mṛ+<ṛ_idðD’ O‘ḅ256b¢*21%¢ḅ¢ḃ256’Ọ  Encrypted message: AX!?ÖÍL¹ JÓ°û0àah4Û{µÌá ^tÝrRÕù#êwðãTÓK"Íû´Ëß!øòOf«  As a hex-string: 9F419458213FD6CD4CB9094A10D3B0FB 8F30E0616834DB7BB517CCE1600A5E74 DD7252D5F923EA77F0E354D34B9F22CD FB80B4CBDF21F80E94F24F9A66AB9112  Explanation: O‘ḅ256b¢*13%¢ḅ¢ḃ256’Ọ O convert each into codepoint ‘ḅ256 convert from bijective base 256 to integer b¢ convert from integer to base N *13 map each to its 13th power %¢ modulo N ḅ¢ convert to integer from base N ḃ256’ convert from integer to bijective base 256 Ọ convert each from codepoint  Where N is encoded by the string: “¥@ɦ⁺€€ṄyȤDƁWĊ;Y^y⁻U ⁸ßɠƁXẹṡWZc'µ÷ḷỊ0ÇtṙA×Ḃß4©qV)iḷỊDƭ Mṛ+<ṛ_idðD’  which is the number 15465347049748408180402050551405372385300458901874153987195606642192077081674726470827949979631079014102900173229117045997489671500506945449681040725068819  Also, this is the RSA method with N given above and public key 13. Cracking this is equivalent to finding the two prime factors of N, which has 512 bits. • I love that your encrypted string looks like your code – Skidsdev Jul 20 '17 at 10:18 • Using this wonderful program, I'm sure I can crack your solution a couple millennia after the heat death of the universe. – Socratic Phoenix Jul 20 '17 at 13:52 • @SocraticPhoenix factorization by trial division can never come close to quadratic sieve. – Leaky Nun Jul 20 '17 at 13:57 • @LeakyNun I don't understand your big math words... – Socratic Phoenix Jul 20 '17 at 13:59 • @SocraticPhoenix your program tries each factor from 2, while quadratic sieve is much faster. It can factorize a 256-bit semiprime in 6 minutes, whereas your program would have taken an eternity. – Leaky Nun Jul 20 '17 at 14:34 ## JavaScript (ES6), 43 + 33 = 76 bytes Cracked by Leaky Nun Encryption function, 43 bytes: s=>[...s].sort(_=>Math.cos(i++),i=0).join  Encrypted message, 33 bytes: NB: This encryption method is browser-dependent. FireFox: "ty a)s kaasoeocr!hTt; o s -cwaoo" Chrome : "oht aasoaoas e)tosr;oky c!-cw T" Edge : "tskso ;- caroteoTha wa soo ay c!)"  • T! a)o khas eotrto-c; o sa cwsaoy – Leaky Nun Jul 19 '17 at 18:41 • @LeakyNun Err ... no. – Arnauld Jul 19 '17 at 18:42 • What does my answer produce instead? – Leaky Nun Jul 19 '17 at 18:43 • Which browser are you using? I'm using Chrome. – Leaky Nun Jul 19 '17 at 18:44 • That was soooo easy to crack! -;) (I used firefox to crack it) – Leaky Nun Jul 19 '17 at 18:46 # Braingolf, Cracked (d1&,&g)&@  Try it online! ## Encrypted message, 45 bytes (UTF-8) °Áݭїϳ{ًչםק{їϳэÁק{|э³קѡ|  ## Hexcodes of encrypted message C2 B0 C3 81 DD AD D1 97 CF B3 C2 90 7B D9 8B D5 B9 D7 9D D7 A7 7B D1 97 CF B3 D1 8D C3 81 D7 A7 7B 7C D1 8D C2 B3 D7 A7 D1 A1 7C C2 85  ## Decrypted message C'mon, this one's *easy*!  ## Explanation (d1&,&g)&@ Implicit input from commandline args (......) Foreach loop, foreach codepoint of input d Split into digits 1 Push 1 &, Reverse &g Concatenate &@ Print  ## Decoder A decoder can be made by changing only 3 characters. Simply remove the 1, and insert $_ inbetween &, and &g

(d&,\$_&g)&@

• Can you provide a TIO? – user41805 Jul 20 '17 at 13:47
• C'mon, this one's *easy*! – KSmarts Jul 20 '17 at 14:59
• @KSmarts Correct! – Skidsdev Jul 20 '17 at 15:05
• g is undocumented? – Leaky Nun Jul 20 '17 at 15:42
• Is this bijective? – Leaky Nun Jul 20 '17 at 15:44

# JavaScript (ES6), 96+9=105 bytes

q=>Buffer(q).map((a,i,d)=>d[i-1]^Math.abs(1e16*Math.sin(d[i]+i))%255).sort((a,i)=>Math.tan(a*i))


Ciphertext (hex-encoded): 7d111c74b99faff76a

Try it online!

### Sample outputs (using V8 engine):

abc123 -> db48ea4f86b9

Hello -> 1b3420f5ab

• Invalid submission: multiple plaintext generate the same ciphertext. For example: "C", "D". This only counts for the first char. Of the 256 possible inputs, only 165 unique outputs. – Mark Jeronimus Sep 20 '18 at 11:10
• It is bijective for the intended range (ASCII A to ASCII z) – iovoid Oct 20 '18 at 1:07
• I just told you it's not. Just try your code with respectively "C" and "D" as the input string. Same output string 76`. – Mark Jeronimus Oct 22 '18 at 7:46