The Challenge

A simple "spy versus spy" challenge.

Write a program with the following specifications:

1. The program may be written in any language but must not exceed 512 characters (as represented in a code block on this site).
2. The program must accept 5 signed 32-bit integers as inputs. It can take the form of a function that accepts 5 arguments, a function that accepts a single 5-element array, or a complete program that reads 5 integers from any standard input.
3. The program must output one signed 32-bit integer.
4. The program must return 1 if and only if the five inputs, interpreted as a sequence, match a specific arithmetic sequence of the programmer's choosing, called the "key". The function must return 0 for all other inputs.

An arithmetic sequence has the property that each successive element of the sequence is equal to its predecessor plus some fixed constant a.

For example, 25 30 35 40 45 is an arithmetic sequence since each element of the sequence is equal to its predecessor plus 5. Likewise, 17 10 3 -4 -11 is an arithmetic sequence since each element is equal to its precessor plus -7.

The sequences 1 2 4 8 16 and 3 9 15 6 12 are not arithmetic sequences.

A key may be any arithmetic sequence of your choosing, with the sole restriction that sequences involving integer overflow are not permitted. That is, the sequence must be strictly increasing, strictly decreasing, or have all elements equal.

As an example, suppose you choose the key 98021 93880 89739 85598 81457. Your program must return 1 if the inputs (in sequence) match these five numbers, and 0 otherwise.

Please note that the means of protecting the key should be of your own novel design. Also, probabilistic solutions that may return false positives with any nonzero probability are not permitted. In particular, please do not use any standard cryptographic hashes, including library functions for standard cryptographic hashes.

The Scoring

The shortest non-cracked submission(s) per character count will be declared the winner(s).

The Counter-Challenge

All readers, including those who have submitted their own programs, are encouraged to "crack" submissions. A submission is cracked when its key is posted in the associated comments section. If a submission persists for 72 hours without being modified or cracked, it is considered "safe" and any subsequent success in cracking it will be ignored for sake of the contest.

See "Disclaimer" below for details on the updated cracking score policy.

Cracked submissions are eliminated from contention (provided they are not "safe"). They should not be edited. If a reader wishes to submit a new program, (s)he should do so in a separate answer.

The cracker(s) with the highest score(s) will be declared the winners along with the developers of the winning programs.

Best of luck. :)

Penultimate standings (pending safety of Dennis' CJam 49 submission).

Unstoppable Crackers

1. Peter Taylor [Ruby 130, Java 342, Mathematica 146*, Mathematica 72*, CJam 37]
2. Dennis [Pyth 13, Python 86*, Lua 105*, GolfScript 116, C 239*]
3. Martin Büttner [Javascript 125, Python 128*, Ruby 175*, Ruby 249*]
4. Tyilo [C 459, Javascript 958*]
5. freddieknets [Mathematica 67*]
6. Ilmari Karonen [Python27 182*]
7. nitrous [C 212*]

*non-compliant submission

Disclaimer (Updated 11:15 PM EST, Aug 26)

With the scoring problems finally reaching critical mass (given two thirds of the cracked submissions are thus far non-compliant), I've ranked the top crackers in terms of number of submissions cracked (primary) and total number of characters in compliant cracked submissions (secondary).

As before, the exact submissions cracked, the length of the submissions, and their compliant/non-compliant status are all marked so that readers may infer their own rankings if they believe the new official rankings are unfair.

My apologies for amending the rules this late in the game.

• How are you going to verify that programs meet point 4? Do you expect people to edit their safe answers to add a proof? Are probabilistic submissions permitted on the basis of assuming that hash functions are ideal and the chance of a collision with another element of the 48-bit (according to your estimate above) space is negligible? Aug 25, 2014 at 8:41
• The scoring system seems to encourage crackers to ignore the shortest locks because they score better by cracking two long locks than two small ones. Aug 25, 2014 at 17:37
• @COTO I think the problem is that you can only get 2 cracking scores, and only the shortest. So why not wait and hope and longer one shows up? For example, Martin now has no incentive to crack my (longer) lock, since he's already cracked two shorter ones. Anyone who cracks mine will now beat him without even having to do a second one. Aug 25, 2014 at 17:51
• I think a better scoring system might be sum of total times between question and crack. That way, cracking a bunch of easy ones can be beaten, and the real reward comes from cracking the really hard ones. Aug 25, 2014 at 21:52
• I'm new to golfing, so maybe it's a stupid question, sorry for that. Why is the code length measured in characters and not in bytes? The latter is literally the memory space that a program occupies, so for me it seems more logical. Eg. the CJam answer is the shortest in characters, but when looking at its size (326 because of unicode) it isn't even in the top 5. So I wonder, is it common convention in golfing to count chars instead of bytes? Aug 26, 2014 at 13:30

CJam, 91 characters

q~]KK#bD#"᫖࿼듋ޔ唱୦廽⻎킋뎢凌Ḏ끮冕옷뿹毳슟夫΢眘藸躦䪕齃噳卤"65533:Bb%"萗縤ᤞ雑燠Ꮖ㈢ꭙ㈶タ敫䙿娲훔쓭벓脿翠❶셭剮쬭玓ୂ쁬䈆﹌⫌稟"Bb=


Stack Exchange is prone to mauling unprintable characters, but copying the code from this paste and pasting it in the CJam interpreter works fine for me.

How it works

After replacing the Unicode string with integers (by considering the characters digits of base 65533 numbers), the following code gets executed:

" Read the integers from STDIN and collect them in an array.                               ";

q~]

" Convert it into an integer by considering its elements digits of a base 20**20 number.   ";

KK#b

" Elevate it to the 13th power modulus 252 ... 701.                                        ";

D#
25211471039348320335042771975511542429923787152099395215402073753353303876955720415705947365696970054141596580623913538507854517012317194585728620266050701%

" Check if the result is 202 ... 866.                                                      ";

20296578126505831855363602947513398780162083699878357763732452715119575942704948999334568239084302792717120612636331880722869443591786121631020625810496866=


Since 13 is coprime to the totient of the modulus (the totient is secret, so you'll just have to trust me), different bases will generate different results, i.e., the solution is unique.

Unless someone can exploit the small exponent (13), the most efficient way of breaking this lock is to factorize the modulus (see RSA problem). I chose a 512-bit integer for the modulus, which should withstand 72 hours of factorization attempts.

Example run

$echo$LANG
en_US.UTF-8
$base64 -d > lock.cjam <<< cX5dS0sjYkQjIgHuiJHhq5bgv7zrk4velOWUse6zjuCtpuW7veK7ju2Ci+uOouWHjOG4ju+Rh+uBruWGleyYt+u/ueavs+6boOyKn+Wkq86i55yY6Je46Lqm5KqV6b2D5Zmz75Wp5Y2kIjY1NTMzOkJiJSIB6JCX57ik4aSe74aS6ZuR54eg4Y+G44ii6q2Z44i244K/5pWr5Jm/5aiy7ZuU7JOt67KT7rO26IS/57+g4p2275+K7IWt5Ymu7Kyt546T4K2C7IGs5IiG77mM4quM56ifIkJiPQ==$ wc -m lock.cjam
91 lock.cjam
$cjam lock.cjam < lock.secret; echo 1$ cjam lock.cjam <<< "1 2 3 4 5"; echo
0

• I have posted a new version since I forgot to remove an unnecessary character from the first one. The secret sequence is still the same, so you can try to crack either one. Aug 25, 2014 at 22:57
• FYI, I'm aborting my factoring attempt. msieve set itself a time limit of 276 hours, but that was just for building the factor base. In that time it found 1740001 rational and 1739328 algebraic entries; it's since had almost 100 hours to process them, and reports sieving in progress b = 46583, 0 complete / 0 batched relations (need 44970493). Sep 13, 2014 at 12:51
• @PeterTaylor: Looks like 512 bits were overkill. Were you trying to factor the integer in my other answer or in this one? Sep 13, 2014 at 13:00
• Oh, oops. Yes, other one. Sep 13, 2014 at 18:16

CJam, 62 characters

"ḡꬼ쏉壥떨ሤ뭦㪐ꍡ㡩折量ⶌ팭뭲䯬ꀫ郯⛅彨ꄇ벍起ឣ莨ຉᆞ涁呢鲒찜⋙韪鰴ꟓ䘦쥆疭ⶊ凃揭"2G#b129b:c~


Stack Exchange is prone to mauling unprintable characters, but copying the code from this paste and pasting it in the CJam interpreter works fine for me.

How it works

After replacing the Unicode string with an ASCII string, the following code gets executed:

" Push 85, read the integers from STDIN and collect everything in an array.               ";

85l~]

" Convert the array of base 4**17 digits into and array of base 2 digits.                 ";

4H#b2b

" Split into chunks of length 93 and 84.                                                  ";

93/~

" Do the following 611 times:

* Rotate array A (93 elements) and B one element to the left.
* B[83] ^= B[14]
* T = B[83]
* B[83] ^= B[0] & B[1] ^ A[23]
* A[92] ^= A[26]
* Rotate T ^ A[92] below the arrays.
* A[92] ^= A[0] & A[1] ^ B[5].                                                        ";

{(X$E=^:T1$2<:&^2$24=^+\(1$26=^_T^@@1$2<:&^3$5=^+@}611*

" Discard the arrays and collects the last 177 generated bits into an array.              ";

;;]434>

" Convert the into an integer and check if the result is 922 ... 593.                     ";

2b9229084211442676863661078230267436345695618217593=


This approach uses Bivium-B (see Algebraic analysis of Trivium-like ciphers), a weakened version of the stream cipher Trivium.

The program uses the sequence of integers as initial state, updates the state 434 times (354 rounds achieve full diffusion) and generates 177 bit of output, which it compares to those of the correct sequence.

Since the state's size is precisely 177 bits, this should suffice to uniquely identify the initial state.

Example run

$echo$LANG
en_US.UTF-8
$base64 -d > block.cjam <<< IgThuKHqrLzsj4nlo6XrlqjhiKTrrabjqpDqjaHjoanmipjvpb7itozuoIDtjK3rrbLul7bkr6zqgKvvjafpg6/im4XlvajqhIfrso3uprrotbfvmL/hnqPojqjguonhhp7mtoHujLPuipzlkaLpspLssJzii5npn6rpsLTqn5PkmKbspYbnlq3itorlh4Pmj60iMkcjYjEyOWI6Y34=$ wc -m block.cjam
62 block.cjam
$cjam block.cjam < block.secret; echo 1$ cjam block.cjam <<< "1 2 3 4 5"; echo
0


Python - 128

Let's try this one:

i=input()
k=1050809377681880902769L
print'01'[all((i>1,i[0]<i[4],k%i[0]<1,k%i[4]<1,i[4]-i[3]==i[3]-i[2]==i[2]-i[1]==i[1]-i[0]))]


(Expects the user to input 5 comma-separated numbers, e.g. 1,2,3,4,5.)

• 32416190039,32416190047,32416190055,32416190063,32416190071 Aug 25, 2014 at 14:07
• Wow, that was fast! You're right! And I'm out. Aug 25, 2014 at 14:10
• Btw, this isn't actually valid, because your five integers don't fit in a 32-bit integer. Aug 25, 2014 at 16:57

Java : 468

Input is given as k(int[5]). Bails early if not evenly spaced. Otherwise, it takes a bit figuring out if all ten hashes are correct. For large numbers, "a bit" can mean ten seconds or more, so it might dissuade crackers.

//golfed
int k(int[]q){int b=q[1]-q[0],i,x,y,j,h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,998860524,888446062,1833324980,1391496617,2075731831};for(i=0;i<4;)if(q[i+1]-q[i++]!=b||b<1)return 0;for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));for(i=0;i<5;i++){for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));if(x!=h[i*2]||y!=h[i*2+1])return 0;}return 1;}int m(int a,int b,int c){long d=1;for(;b-->0;d=(d*a)%c);return (int)d;}

// line breaks
int k(int[]q){
int b=q[1]-q[0],i,x,y,j,
h[]=new int[]{280256579,123883276,1771253254,1977914749,449635393,
998860524,888446062,1833324980,1391496617,2075731831};
for(i=0;i<4;)
if(q[i+1]-q[i++]!=b||b<1)
return 0;
for(i=1;i<6;b=m(b,b/(i++*100),(1<<31)-1));
for(i=0;i<5;i++){
for(j=1,x=b,y=b/2;j<6;x=m(x,q[i]%100000000,(1<<31)-1),y=m(y,q[i]/(j++*1000),(1<<31)-1));
if(x!=h[i*2]||y!=h[i*2+1])
return 0;
}
return 1;
}
int m(int a,int b,int c){
long d=1;for(;b-->0;d=(d*a)%c);
return (int)d;
}

• Your code hangs if input arithmetic sequence is descending. Or at least, takes a really long time. Which makes me think the secret code is ascending... Aug 25, 2014 at 21:04
• @KeithRandall Oops. Let's add four bytes to make descending sequences take an unusually short amount of time, further reinforcing your belief. Aug 25, 2014 at 21:45

Java : 342

int l(int[]a){String s=""+(a[1]-a[0]);for(int b:a)s+=b;char[]c=new char[11];for(char x:s.toCharArray())c[x<48?10:x-48]++;for(int i=0;i<11;c[i]+=48,c[i]=c[i]>57?57:c[i],i++,s="");for(int b:a)s+=new Long(new String(c))/(double)b;return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;}


Here's a string-based locker that depends on both the input character count and the specific input. The sequence might be based on obscure pop culture references. Have fun!

A bit ungolfed:

int lock(int[]a){
String s=""+(a[1]-a[0]);
for(int b:a)
s+=b;
char[]c=new char[11];
for(char x:s.toCharArray())
c[x<48?10:x-48]++;
for(int i=0;i<11;c[i]+=48,
c[i]=c[i]>57?57:c[i],
i++,
s="");
for(int b:a)
s+=new Long(new String(c))/(double)b;
return s.equals("-3083.7767567702776-8563.34366442527211022.4345579010483353.1736981951231977.3560837512646")?1:0;
}

• 8675309? 90210? Aug 26, 2014 at 20:46
• @Malachi Two outstanding references, no doubt, but I can neither confirm nor deny their applicability to this exercise. Aug 26, 2014 at 21:09
• lol, I haven't completely figured out how this challenge works completely yet, I may give it a shot later when I am at home. Aug 26, 2014 at 21:36
• Initial term is -8675309, delta is 5551212. Aug 27, 2014 at 9:36
• @PeterTaylor Nicely done :) Aug 27, 2014 at 12:37

Python, 147

Edit: shorter version based on Dennis' comment. I updated the sequence too to avoid leaking any information.

def a(b):
c=1
for d in b:
c=(c<<32)+d
return pow(7,c,0xf494eca63dcab7b47ac21158799ffcabca8f2c6b3)==0xa3742a4abcb812e0c3664551dd3d6d2207aecb9be


Based on the discrete logarithm problem which is believed to be uncrackable, however the prime I'm using is probably too small to be secure (and it may have other issues, I don't know). And you can brute-force it of course, since the only unknowns are two 32-bit integers.

• Discrete logarithms are a lot harder that I thought. My cracker has been at this for 26 hours. I give up. Aug 27, 2014 at 4:28
• You could solve the sign problem by initializing c=1, computing c=(c<<32)+d and changing the constant accordingly. Aug 27, 2014 at 17:44
• assert a([-1154709934+316804249*k for k in range(5)]) works for me :) Apr 8, 2023 at 12:31

Javascript 125

This one should be cracked pretty quickly. I'll follow up with something stronger.

function unlock(a, b, c, d, e)
{
return (e << a == 15652) && (c >> a == 7826) && (e - b == d) && (d - c - a == b) ? 1 : 0;
}

• 0, 3913, 7826, 11739, 15652 Aug 25, 2014 at 15:20
• yep you got it :) Aug 25, 2014 at 15:43

Ruby, 175

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
p a[2]*(a[1]^a[2]+3)**7==0x213a81f4518a907c85e9f1b39258723bc70f07388eec6f3274293fa03e4091e1?1:0


Unlike using a cryptographic hash or srand, this is provably unique (which is a slight clue). Takes five numbers via STDIN, delimited by any non-digit, non-newline character or characters. Outputs to STDOUT.

• Yep, forgot they were signed. Aug 25, 2014 at 16:07
• 622238809,1397646693,2173054577,2948462461,3723870345 (my previous guess had a mistake, but this one is tested). I don't think this is valid though, because the last number doesn't fit in a signed 32-bit integer. Aug 25, 2014 at 16:16

GolfScript (116 chars)

Takes input as space-separated integers.

~]{2.5??:^(&}%^base 2733?5121107535380437850547394675965451197140470531483%5207278525522834743713290685466222557399=

• -51469355 -37912886 -24356417 -10799948 2756521 Aug 25, 2014 at 22:39
• Nice work. Did you exploit the small exponent? Aug 25, 2014 at 22:54
• No, I factorized the modulus. Took only 13 seconds using primo's Multiple Polynomial Quadratic Sieve and PyPy. Aug 25, 2014 at 23:00
• In that case I might as well abandon my current golfing it down by using a compactly expressed modulus. If the result has to be something like 1024 bits to be safe from factoring then even using a base-256 representation it's going to be too long. Aug 25, 2014 at 23:03
• I hope not. My answer uses the same idea as yours, but with a 512 bit modulus and an even smaller exponent (13). Given the 72 hour time limit, that might be enough... Aug 25, 2014 at 23:08

SOLVED BY Tyilo -- READ EDIT BELOW

int c (int* a){
int d[4] = {a[1] - a[0], a[2] - a[1], a[3] - a[2], a[4] - a[3]};
if (d[0] != d[1] || d[0] != d[2] || d[0] != d[3]) return 0;
int b[5] = {a[0], a[1], a[2], a[3], a[4]};
int i, j, k;
for (i = 0; i < 5; i++) {
for (j = 0, k = 2 * i; j < 5; j++, k++) {
k %= i + 1;
b[j] += a[k];
}
}
if (b[0] == 0xC0942 - b[1] &&
b[1] == 0x9785A - b[2] &&
b[2] == 0x6E772 - b[3] &&
b[3] == 0xC0942 - b[4] &&
b[4] == 0xB6508 - b[0]) return 1;
else return 0;
}


We need someone to write a C solution, don't we? I'm not impressing anybody with length, I'm no golfer. I hope it's an interesting challenge, though!

I don't think there's an obvious way to crack this one, and I eagerly await all attempts! I know this solution to be unique. Very minimal obfuscation, mostly to meet length requirements. This can be tested simply:

int main(){
a[5] = {0, 0, 0, 0, 0} /* your guess */
printf("%d\n", c(a));
return 0;
}


P.S. There's a significance to a[0] as a number in its own right, and I'd like to see somebody point it out in the comments!

EDIT:

Solution: 6174, 48216, 90258, 132300, 174342

While this is not the method used (see the comments), I did happen to crack my own cipher with a very easy bruteforce. I understand now it is vitally important to make the numbers large. The following code can crack any cipher where upper_bound is a known upper bound for a[0] + a[1] + a[2] + a[3] + a[4]. The upper bound in the above cipher is 457464, which can be derived from the system of equations of b[] and some working-through of the algorithm. It can be shown that b[4] = a[0] + a[1] + a[2] + a[3] + a[4].

int a[5];
for (a[0] = 0; a[0] <= upper_bound / 5; a[0]++) {
for (a[1] = a[0] + 1; 10 * (a[1] - a[0]) + a[0] <= upper_bound; a[1]++) {
a[2] = a[1] + (a[1] - a[0]);
a[3] = a[2] + (a[1] - a[0]);
a[4] = a[3] + (a[1] - a[0]);
if (c(a)) {
printf("PASSED FOR {%d, %d, %d, %d, %d}\n", a[0], a[1], a[2], a[3], a[4]);
}
}
printf("a[0] = %d Checked\n", a[0]);
}


With a[0] = 6174, this loop broke my work in a little under a minute.

• Solution: 6174, 48216, 90258, 132300, 174342. Aug 25, 2014 at 19:32
• Wow that was fast. Nice one. Bruteforced, or did you find something clever I missed? Aug 25, 2014 at 19:33
• I used Mathematica's symbolic evaluation like so: ghostbin.com/paste/jkjpf screenshot: i.imgur.com/2JRo7LE.png Aug 25, 2014 at 19:36
• Re the edit: I did basically the same thing, but fudged the upper at 500k. Got the answer and saw that Tyilo had already posted it :( Aug 25, 2014 at 19:50
• @Geobits That's a surprisingly accurate guess. Should've put some more 0's on the ends of those numbers. Aug 25, 2014 at 19:53

Mathematica 80 67

f=Boole[(p=NextPrime/@#)-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&


Running:

f[{1,2,3,4,5}] (* => 0 *)


Probably pretty easy to crack, might also have multiple solutions.

Update: Improved golfing by doing what Martin Büttner suggested. Functionality of the function and the key hasn't changed.

• @MartinBüttner Improving answers to get higher score when you crack them. Smart ;P Aug 25, 2014 at 18:03
• Huh, turns out I skipped the paragraph about scoring for the counter challenge. I thought that was just for the fun of it without any score at all. Although I don't think it would make sense for me shorten solutions I want to crack because that would reduce my score. Aug 25, 2014 at 18:09
• {58871,5592,-47687,-100966,-154245} Aug 25, 2014 at 21:20
• @freddieknets Not the solution I used when creating it. Didn't know that NextPrime could return negative values. How did you find it? Aug 25, 2014 at 21:28
• Then your key is not unique :p. I just ran a few tests - there really aren't that many numbers where NextPrime[#]-# evaluates to 31, so that's an easy way to crack it. Aug 25, 2014 at 21:31

Python27, 283 182

Alright, I am very confident in my locker, however it is quite long as I've added 'difficult to reverse' calculations to the input, to make it well - difficult to reverse.

import sys
p=1
for m in map(int,sys.argv[1:6]):m*=3**len(str(m));p*=m<<sum([int(str(m).zfill(9)[-i])for i in[1,3,5,7]])
print'01'[p==0x4cc695e00484947a2cb7133049bfb18c21*3**45<<101]


edit: Thanks to colevk for the further golfing. I realized during editing that there was a bug as well as a flaw in my algorithm, maybe I'll have better luck next time.

• This is invariant under reordering of the arguments, so it's not a valid locker. Aug 25, 2014 at 18:26
• Besides, I suspect the code as posted is buggy: the key 121174841 121174871 121174901 121174931 121174961 works, but only if the list [1,3,5,7] on line 7 is replaced with [1,3,5,7,11]. Aug 25, 2014 at 19:18
• Darn, yes I was just fixing my typo, during which I made a crucial mistake in my algorithm, leaving it very easy to crack :| Aug 25, 2014 at 19:33
• Actually, finding and fixing the bug was the difficult part; given your algorithm, factoring the constant was kind of an obvious thing to try. Aug 25, 2014 at 19:39

Mathematica 142 146

EDIT: key wasn't unique, added 4 chars, now it is.

n=NextPrime;
f=Boole[
FromDigits /@ (
PartitionsQ[n@(237/Plus@##) {1, ##} + 1] & @@@
IntegerDigits@n@{Plus@##-37*Log[#3],(#1-#5)#4}
) == {1913001154,729783244}
]&


Usage:

f[1,2,3,4,5]   (* => 0 *)

• Initial term 256208, delta -5. Aug 26, 2014 at 13:34
• Dang, then still it isn't unique, as this isn't my original key. Did you bruteforce? Aug 26, 2014 at 13:37
• Test it, I might have made a mistake because I don't have access to Mathematica to test. Each stage is using brute force, but it's not much computer time. The approach is to work backwards to the output of IntegerDigits and then factor to get candidates for the initial term and delta. Aug 26, 2014 at 13:42
• But there's no way this approach could be unique anyway. The second of the five inputs is only used in a sum which is passed to NextPrime; if we vary it by plus or minus one, at least one of those will give the same next prime. Aug 26, 2014 at 14:02
• yes but for a arithmetic sequence -as is the required input- it was supposed to be unique. Aug 26, 2014 at 20:54

CJam, 49 characters

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b[1q~]8H#b%!


Try it online.

How it works

" Push a string representing a base 65536 number and convert it to an integer.            ";

"腕옡裃䃬꯳널֚樂律ࡆᓅ㥄뇮┎䔤嬣ꑙ䘿휺ᥰ籃僾쎧諯떆Ἣ餾腎틯"2G#b

" Prepend 1 to the integers read from STDIN and collect them into an array.               ";

[1q~]

" Convert that array into an integer by considering it a base 2**51 number.               ";

8H#b

" Push the logical NOT of the modulus of both computed integers.                          ";

%!


The result will be 1 if and only if the second integer is a factor of the first, which is a product of two primes: the one corresponding to the secret sequence and another that doesn't correspond to any valid sequence. Therefore, the solution is unique.

Factorizing a 512 bit integer isn't that difficult, but I hope nobody will be able to in 72 hours. My previous version using a 320 bit integer has been broken.

Example run

$echo$LANG
en_US.UTF-8
$base64 -d > flock512.cjam <<< IuiFleyYoeijg+SDrOqvs+uEkNaa76a/5b6L4KGG4ZOF76Gi46WE64eu4pSO5JSk5ayj6pGZ5Ji/7Zy64aWw57GD5YO+7I6n6Kuv65aG7qK04byr6aS+6IWO7rSn7YuvIjJHI2JbMXF+XThII2IlIQ==$ wc -m flock512.cjam
49 flock512.cjam
$cjam flock512.cjam < flock512.secret; echo 1$ cjam flock512.cjam <<< "1 2 3 4 5"; echo
0

• I've had msieve running on it for over 24 hours, but since its self-imposed time limit is 276.51 CPU-hours and I've only given it one CPU I'm not optimistic. Aug 29, 2014 at 21:55
• -2005516409 -1431071926 -856627443 -282182960 292261523. Cracked with a Coppersmith attack that takes less than a CPU-second. Jan 5 at 19:27
• @qbt937 Not me coming up with this idea and then seeing this comment...nice work! Jan 15 at 0:39

Cracked by @Dennis in 2 hours

Just a simple one to get things started - I fully expect this to be quickly cracked.

Pyth, 13

h_^ZqU5m-CGdQ


Takes comma separated input on STDIN.

Run it like this (-c means take program as command line argument):

$echo '1,2,3,4,5' | python3 pyth.py -c h_^ZqU5m-CGdQ 0  Fixed the program - I had not understood the spec. This language might be too esoteric for this competition - If OP thinks so, I will remove it. • Have you just given away that 1,2,3,4,5 is the key? Aug 25, 2014 at 9:55 • Every input I tried returned 1, did you switch 1 and 0 as output? Aug 25, 2014 at 17:27 • Sorry, I didn't understand the Output vs. Return distinction - the program should work now. Same underlying algorithm. Aug 25, 2014 at 21:20 • 97,96,95,94,93 (I just killed my cracking score.) Aug 25, 2014 at 23:23 • @Dennis Well done. The cracking score system needs to be changed - it's creating some really weird incentives. Aug 25, 2014 at 23:37 Lua 105 I suspect it won't be long before it's cracked, but here we go: function f(a,b,c,d,e) t1=a%b-(e-2*(d-b)) t2=(a+b+c+d+e)%e t3=(d+e)/2 print(t1==0 and t2==t3 and"1"or"0") end  (spaces added for clarity, but are not part of count) • 3, 7, 11, 15, 19 or 6, 14, 22, 30, 38 Aug 26, 2014 at 4:50 • @Dennis: sadly it is neither of those. I'll have to work on it a bit later to ensure the non-uniqueness. Aug 26, 2014 at 11:15 • t1==0 whenver S is increasing. Also, both conditions are homogeneous; if S is a solution, so is kS. Aug 26, 2014 at 16:55 Perl - 256 sub t{($z,$j,$x,$g,$h)=@_;$t="3"x$z;@n=(7,0,split(//,$g),split(//,$h),4);@r=((2)x6,1,1,(2)x9,4,2,2,2);$u=($j+1)/2;for$n(0..$#r+1){eval{substr($t,$j,1)=$n[$n]};if($@){print 0; return}$j+=$r[$n]*$u}for(1..$x){$t=pack'H*',$t;}eval$t;if($@||$t!~/\D/){print 0}}  I had to put in a lot of error handling logic and this can definitely be golfed down a lot more. It will print a 1 when you get the right five numbers. It will hopefully print a 0 for everything else (might be errors or nothing, I don't know). If anyone wants to help improve the code or golf it more, feel free to help out! Call with: t(1,2,3,4,5);  Ruby - 130 Based on Linear Feedback Shift Register. Inputs by command line arguments. Should be unique based on the nature of LFSRs. Clue: ascending and all positive. Will give more clues if no one solves it soon. x=($*.map{|i|i.to_i+2**35}*'').to_i
(9**8).times{x=((x/4&1^x&1)<<182)+x/2}
p x.to_s(36)=="qnsjzo1qn9o83oaw0a4av9xgnutn28x17dx"?1:0

• Initial value 781783, increment 17982811 Aug 26, 2014 at 10:39
• @PeterTaylor Argh... =) Aug 26, 2014 at 10:43

Ruby, 249

a=gets.scan(/\d+/).map(&:to_i)
a.each_cons(2).map{|x,y|x-y}.uniq[1]&&p(0)&&exit
r=(a[0]*a[1]).to_s(5).tr'234','(+)'
v=a[0]<a[1]&&!r[20]&&(0..3).select{|i|/^#{r}$/=~'%b'%[0xaa74f54ea7aa753a9d534ea7,'101'*32,'010'*32,'100'*32][i]}==[0]?1:0rescue 0 p v  Should be fun. Who needs math? • 309, 77347, 154385, 231423, 308461 but I don't think it's unique. Aug 26, 2014 at 14:54 • Yeah, it's not. For the same regex (i.e. product of the first two numbers), I also find 103, 232041, 463979, 695917, 927855 and 3, 7966741, 15933479, 23900217, 31866955. And I'm pretty sure there are other valid regexes by using additional +s. Aug 26, 2014 at 14:58 • Sorry, I guess I messed up the test string. There was supposed to be only one regexp with a unique factorization. Aug 26, 2014 at 15:00 • If you want to try to fix it, make sure to take possessive quantifiers into account. I can also create a larger, equivalent regex by inserting () or similar. Aug 26, 2014 at 15:02 C 93 bytes A simple hash. To follow the rule of unique solution, I bruteforced all the candidates, which took quite some core-hours. Of course the solution can be found in the same way. The function f accepts a pointer to the 5 input integers and outputs 1 for the unique solution, 0 otherwise. i=1e5;f(int*x){for(;--i;)x[i&3]+=(x[4]^=x[i&3])*9>>3;return!memcmp(x,"U|]v-W^Scv1(-8V8",16);}  For more adventurous hackers, here's a variant with 64-bit security* (89 bytes), which I could not verify to have a unique solution due to too big search space (but the chance of it happening is less than 1 in a billion). i=1e5;f(int*x){for(;--i;)x[i&3]+=(x[4]^=x[i&3])*9>>3;return!memcmp(x,"'=P(=31qlite",12);}  * 64-bit security meaning 2^64 function calls. The number of required bit operations is quite bigger. Javascript 958 Converts the inputs to a number of data types and performs some manipulations relevant to each data type along the way. Should be fairly easily reversed for anyone that takes the time. function encrypt(num) { var dateval = new Date(num ^ (1024-1) << 10); dateval.setDate(dateval.getDate() + 365); var dateString = (dateval.toUTCString() + dateval.getUTCMilliseconds()).split('').reverse().join(''); var result = ""; for(var i = 0; i < dateString.length; i++) result += dateString.charCodeAt(i); return result; } function unlock(int1, int2, int3, int4, int5) { return encrypt(int1) == "5549508477713255485850495848483249555749321109774324948324410511470" && encrypt(int2) == "5756568477713252485848495848483249555749321109774324948324410511470" && encrypt(int3) == "5149538477713248485856485848483249555749321109774324948324410511470" && encrypt(int4) == "5356498477713256535853485848483249555749321109774324948324410511470" && encrypt(int5) == "5748568477713251535851485848483249555749321109774324948324410511470" ? 1 : 0; }  • Brute forced: 320689, 444121, 567553, 690985, 814417 Aug 25, 2014 at 21:20 • @Tyilo If you stop now, I think no cracker can beat your score. ;) Aug 25, 2014 at 21:48 • @MartinBüttner Unless this can be golfed to under 512 per the OP, I don't think it counts. Aug 25, 2014 at 22:43 C, 239 (Cracked by Dennis) Go here for my updated submission. Could probably be golfed a little more thoroughly. Admittedly, I haven't taken the time to prove the key is unique (it probably isn't) but its definitely on the order of a hash collision. If you crack it, please share your method :) p(long long int x){long long int i;x=abs(x); for (i=2;i<x;i++) {if ((x/i)*i==x) return 0;}return 1;} f(a,b,c,d,e){char k[99];long long int m;sprintf(k,"%d%d%d%d%d",e,d,c,b,a); sscanf(k,"%lld",&m);return p(a)&&p(b)&&p(c)&&p(d)&&p(e)&&p(m);}  • So, 0 0 0 0 0? Aug 26, 2014 at 0:01 • Sigh that was a bug, but yes that works. – Orby Aug 26, 2014 at 0:06 • I've updated with a corrected version that should be a little more interesting ;) – Orby Aug 26, 2014 at 0:14 • See the corrected version here. – Orby Aug 26, 2014 at 0:27 C, 212 by Orby -- Cracked https://codegolf.stackexchange.com/a/36810/31064 by Orby has at least two keys: 13 103 193 283 373 113 173 233 293 353  Orby asked for the method I used to crack it. Function p checks whether x is prime by checking x%i==0 for all i between 2 and x (though using (x/i)*i==x instead of x%i==0), and returns true if x is a prime number. Function f checks that all of a, b, c, d and e are prime. It also checks whether the number m, a concatenation of the decimal representations of e, d, c, b and a (in that order), is prime. The key is such that a,b,c,d,e and m are all prime. Green and Tao (2004) show that there exist infinitely many arithmetic sequences of primes for any length k, so we just need to look for these sequences that also satisfy m being prime. By taking long long as being bounded by -9.223372037e+18 and 9.223372037e+18, we know that for the concatenated string to fit into long long, the numbers have an upper bound of 9999. So by using a python script to generate all arithmetic sequences within all primes < 10000 and then checking whether their reverse concatenation is a prime, we can find many possible solutions. For some reason I came up with false positives, but the two above are valid according to the program. In addition there may be solutions where e is negative and the rest are positive (p uses the modulus of x), but I didn't look for those. The keys I gave are all arithmetic sequences but Orby's script doesn't appear to actually require the inputs to be an arithmetic sequence, so there may be invalid keys too. MATLAB: Apparently invalid Very simple, you just have to generate the right random number. function ans=t(a,b,c,d,e) rng(a) r=@(x)rng(rand*x) r(b) r(c) r(d) r(e) rand==0.435996843156676  It can still error out, but that shouldn't be a problem. • This approach is prohibited in the comments. If it's not mentioned in the question, propose an edit. Sorry. Aug 26, 2014 at 10:51 • @PeterTaylor I guess I am out then, I will just leave it here without score as I am curious whether someone can find a weakness. Aug 26, 2014 at 10:54 MATLAB (with Symbolic Toolbox), 173 characters This isn't an official entry and won't count towards anyone's cracking score, but it will net you mad bragging rights. ;) function b=L(S),c=sprintf('%d8%d',S(1),S(2)-S(1));b=numel(unique(diff(S)))==1&&numel(c)==18&&all(c([8,9])==c([18,17]))&&isequal(c,char(sym(sort(c,'descend'))-sym(sort(c))));  The symbolic toolbox is only required to handle subtraction of big integers. Brute forcing it should be a dog, but if you're familiar with the series it involves, the solution is trivial. Python 2 (91) Edit: This isn't allowed because the argument for uniqueness is probabilistic. I give up. s=3 for n in input():s+=pow(n,s,7**58) print s==0x8b5ca8d0cea606d2b32726a79f01adf56f12aeb6e  Takes lists of integers as input, like [1,2,3,4,5]. The loop is meant to operate on the inputs in an annoying way, leaving a tower of sums and exponents. The idea is like discrete log, but with messy complication instead of mathematical simplicity. Maybe the compositeness of the of the modulus is a vulnerability, in which case I could make it something like 7**58+8. I don't really know how I'd prove that my key is the only one, but the range of outputs is at least 10 times bigger than the range of inputs, so probably? Though maybe only a small fraction of potential outputs are achievable. I could always increase the number of digits at the cost of characters. I'll leave it up to you to decide what's fair. Happy cracking! Mathematica - 72 Version 2 of my script, with the same key as the one intended for my version 1. This basically removes negative prime numbers for NextPrime. f=Boole[(p=Abs[NextPrime/@#])-#=={18,31,6,9,2}&&BitXor@@#~Join~p==1000]&  Running: f[{1,2,3,4,5}] (* => 0 *)  • Assuming that I've correctly understood what your code does, I get several solutions of which the smallest is initial term 9244115, delta 25. Aug 27, 2014 at 11:39 • @PeterTaylor I can confirm that that one is valid. Aug 27, 2014 at 12:12 • @PeterTaylor correct, another key is 1073743739, 1073886396, 1074029053, 1074171710, 1074314367 Aug 27, 2014 at 14:29 Python, 86 characters a,b,c,d,e=input() print 1if(a*c^b*e)*d==0xd5867e26a96897a2f80 and b^d==48891746 else 0  Enter the numbers like 1,2,3,4,5. > python 36768.py <<< "1,2,3,4,5" 0 > python 36768.py <<< "[REDACTED]" 1  • This isn't a valid submission; it accepts the input 1,0,1,63021563418517255630720,0. Aug 27, 2014 at 3:01 • @Dennis Fixed. I hope it's valid now. Aug 27, 2014 at 5:03 • 19960211, 31167202, 42374193, 53581184, 64788175 Aug 27, 2014 at 5:07 • @Dennis Correct and awesome. I think I'm very poor at math. Aug 27, 2014 at 5:13 • @Dennis, 63021563418517255630720 isn't a 32-bit number. Aug 27, 2014 at 8:59 Python, 78 (Cracked by Tyilo in 14 mins) Fun! def L(a): return 1 if a==[(i-i**6) for i in bytearray(' ','utf-8')] else 0  Okay, it doesn't display properly here :( Expects a list of five numbers, eg. [1,2,3,4,5] • Pretty easy: [-481890276, -594823292, -728999970, -887503650, -1073741792] Aug 27, 2014 at 9:03 • Thought so, well done :) Aug 27, 2014 at 9:05 CJam, 37 characters (broken) "煷➻捬渓类ⶥ땙ዶ꾫㞟姲̷ᐂ㵈禙鰳쥛忩蔃"2G#b[1q~]4G#b%!  Try it online. How it works See my new answer. Example run $ echo $LANG en_US.UTF-8$ base64 -d > flock.cjam <<< IueFt+Keu+aNrOa4k+exu+K2peuVmeGLtuq+q+Oen+Wnsu6AhMy34ZCC47WI56aZ6bCz7KWb5b+p6JSDIjJHI2JbMXF+XTRHI2IlIQ==
$wc -m flock.cjam 37 flock.cjam$ cjam flock.cjam < flock.secret; echo
1
$cjam flock.cjam <<< "1 2 3 4 5"; echo 0  • 737262825 208413108 3974530688 3445680972 2916831257 works but isn't an arithmetic progression. Factored in 3 hours 20 minutes. 512-bit numbers were apparently doable in 72 hours for$75 on EC2 two years ago, so I think that would have been safe. Aug 27, 2014 at 22:15
• @PeterTaylor: That returns 1, but the last three integers are greater than MAX_INT, so it's not a valid key. That being said, 3 h 20 m is pretty impressive. The algorithm I was using took 16 hours for a 256-bit semiprime... Aug 27, 2014 at 23:59
• I thought there must be some negative numbers in there somewhere because the deltas were almost right but not quite. I'll get on to it. Aug 28, 2014 at 7:08
• 737262825 208413109 -320436607 -849286323 -1378136039 Aug 28, 2014 at 7:27
• @PeterTaylor: That's the one. I hope the 512 bit version lasts longer. Aug 28, 2014 at 17:37