Lockers vs. Crackers: The Five-Element Sequence

31

2

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).

If there's any confusion, please feel free to ask or comment.

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.

Please do not crack your own submission.

Best of luck. :)

Leaderboard

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

Secure Lockers

  1. CJam 49, Dennis
  2. CJam 62, Dennis safe
  3. CJam 91, Dennis safe
  4. Python 156, Maarten Baert safe
  5. Perl 256, chilemagic safe
  6. Java 468, Geobits safe

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.

COTO

Posted 2014-08-25T07:14:05.593

Reputation: 3 701

6How 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? – Peter Taylor – 2014-08-25T08:41:04.053

If a language does not have fine-grained control over its return value, if it OK, to exit with an error if the key is given, and not otherwise? – isaacg – 2014-08-25T09:20:52.710

Is Mathematica permitted? not everyone will be able to test it so it will have a big advantage over other languages. – rdans – 2014-08-25T10:27:16.497

I really think built-in cryptographic functions should be ruled out, as the only feasible solution is bruteforce, which is practically impossible. You will end up with several solutions in the form return (hash(inputs) == myHashedKey), which are all 'unbreakable' as far as the scope of this competition runs. – stokastic – 2014-08-25T12:26:32.610

@isaacg: I'm going to have to say "no" to allowing errors as output. The program/function should always terminate normally. However if a particular language doesn't have the ability to output integer 1 and 0 specifically, the program may output any two distinct values so long as they're documented along with the submission. – COTO – 2014-08-25T12:29:08.437

@stokastic: You're right. Ryan thought of the idea first, hence his entry can stay. I'll add the "no standard crypto hashes" rule to the OP. – COTO – 2014-08-25T12:30:59.013

@coto I don't mind my entry being disallowed. It will make the challenge more interesting i.e. i'm voluntarily withdrawing my submission. – rdans – 2014-08-25T12:47:11.570

@PeterTaylor: A proof would be nice, but we'll take it on good faith that each submission identifies one and only one input sequence. Probabilistic solutions that may return false positives with any nonzero probability are not permitted. – COTO – 2014-08-25T12:48:14.583

"Probabilistic solutions that may return false positives with any nonzero probability are not permitted" makes the problem a lot more interesting, since it effectively rules out both cryptographic hashes and the cheat I was going to do, srand(input). – histocrat – 2014-08-25T14:19:30.020

If you don't accept probabilistic methods, you don't have to rule out hashes. – Dennis – 2014-08-25T14:37:26.387

Are we allowed to use built-in random, provided the seed is available to the cracker? – stokastic – 2014-08-25T15:16:11.180

@stokastic: I would very much like to say "yes", but it opens up too many possibilities for abuse. For example, using the PRNG in $30K-a-license Exclusive Software X to hide constants where no one will ever find them. Hence the answer is "No". Using a PRNG to hide constants a clever idea, though, and you officially get credit for it. – COTO – 2014-08-25T15:34:21.870

2The scoring system seems to encourage crackers to ignore the shortest locks because they score better by cracking two long locks than two small ones. – Peter Taylor – 2014-08-25T17:37:23.823

@PeterTaylor: It was my thinking that (generally speaking) the longer a lock is, the more intractable the the problem of cracking it. I wanted the scoring system to reflect this in some way. I realize there are exceptions to the rule, and that there are other drawbacks. At this point it would be improper to amend the scoring rules. – COTO – 2014-08-25T17:44:30.750

3@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. – Geobits – 2014-08-25T17:51:47.560

When should we post the answer if no-one has cracked it? After 72 hours after submission? Another deadline? – Tyilo – 2014-08-25T18:47:53.043

@Geobits: Actually, one of the reasons I put the rule in was to discourage a single reader from cracking all the entries, which I figured would discourage anyone else from attempting. When I post the day 1 leaderboard later this evening, Martin will get a special mention regardless of where he ranks according to official score. He's really going to town on people's entries. – COTO – 2014-08-25T18:48:07.787

@Tyilo: If you're still around after 72 hours, absolutely. The crackers will want to know how you stumped them. – COTO – 2014-08-25T18:49:04.017

1I 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. – isaacg – 2014-08-25T21:52:29.607

Neither the 128 byte nor the 175 byte submission I cracked were valid, so you shouldn't include them in the score, I think. – Martin Ender – 2014-08-26T07:45:55.263

1I'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? – freddieknets – 2014-08-26T13:30:12.343

@freddieknets: Honestly I don't know what the usual convention for bytes v. chars is. I'll stick with chars in this challenge, but if the convention is to count bytes, I'll use that in future. – COTO – 2014-08-26T13:48:15.333

@MartinBüttner: Will do. I'll update the leaderboard now. – COTO – 2014-08-26T13:50:02.030

@freddieknets, the default is bytes, as specified in the code-golf tag wiki, but some people prefer to count in characters.

– Peter Taylor – 2014-08-26T13:58:00.490

1I think this contest would have been better without requiring a unique key. It's impossible to verify, probabilistic arguments require a long "hash" which takes up most of the characters, and additional keys only favor the cracker. – xnor – 2014-08-26T18:45:00.900

my version 1 is not valid as I know at least to keys for it, so @freddieknets should have a *. I can't disclose the key right now as it's the solution to my v2 script. – Tyilo – 2014-08-26T21:26:00.347

@xnor: Probabilistic arguments are forbidden. That's what makes the challenge interesting (for me), as you cannot use a hash at all.

– Dennis – 2014-08-26T23:11:46.903

@Dennis Thanks, I hadn't seen that ruling; that sadly disqualifies my solution. A bunch of answers fail uniqueness then, including some on the leaderboard. – xnor – 2014-08-26T23:35:45.380

@xnor: Yeah, that rule was a little buried. I've edited the question to make it more prominent. – Dennis – 2014-08-26T23:37:35.520

@COTO I feel like discrete logarithm and the RSA problem, which a lot of the answers use, should be disallowed for being "standard cryptographic hashes". – xnor – 2014-08-26T23:38:07.363

@xnor: RSA is asymmetric encryption, not hashing. As shown here, it can be used for message authentication codes, but it makes a terrible hash; anyone knowing the factorization of the modulus can easily reverse it. – Dennis – 2014-08-26T23:41:49.047

@COTO Then please change the wording "Please note that the means of protecting the key should be of your own novel design." Unless some of our golfers would like to reveal to be Professor Rivest, Professor Shamir, or Professor Adleman. – xnor – 2014-08-26T23:44:42.877

@Dennis That may be true for RSA, but discrete log is not known to have a trapdoor. What is then the distinction between one-way functions and hashes? – xnor – 2014-08-26T23:49:46.337

@xnor: There are different definitions of hash function. In crytography, one usually requires that you can't compute H(M*X) gives H(M) and X. With the discrete logarithm approach, that's perfectly possible, since G**(M+X)=G**M * G**X and G**(M*X)=(G**M)**X. – Dennis – 2014-08-27T00:20:22.337

1@xnor: Truth be known, I added the "no cryptographic hashes" rule believing that RSA was an example of a cryptographic hash ("cryptographic hash" being a catch-all for "algorithm for generating a digital signature" in my ignorance). The goal was to rule out submissions relying on long-established algorithms that are (barring some world-changing advance in number theory) guaranteed to be unbreakable by anything other than brute force. The intent was to promote novelty. I unfortunately don't have the background to determine whether any given algorithm is a significant departure... – COTO – 2014-08-27T03:44:40.933

from an existing bulwark in the field of encryption, and thus "novel". – COTO – 2014-08-27T03:45:33.393

Answers

3

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

Dennis

Posted 2014-08-25T07:14:05.593

Reputation: 196 637

6

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

Dennis

Posted 2014-08-25T07:14:05.593

Reputation: 196 637

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. – Dennis – 2014-08-25T22:57:34.297

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). – Peter Taylor – 2014-09-13T12:51:38.593

@PeterTaylor: Looks like 512 bits were overkill. Were you trying to factor the integer in my other answer or in this one? – Dennis – 2014-09-13T13:00:11.030

Oh, oops. Yes, other one. – Peter Taylor – 2014-09-13T18:16:34.730

4

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.)

Falko

Posted 2014-08-25T07:14:05.593

Reputation: 5 307

332416190039,32416190047,32416190055,32416190063,32416190071 – Martin Ender – 2014-08-25T14:07:27.370

Wow, that was fast! You're right! And I'm out. – Falko – 2014-08-25T14:10:07.157

3Btw, this isn't actually valid, because your five integers don't fit in a 32-bit integer. – Martin Ender – 2014-08-25T16:57:38.463

4

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;
}

Geobits

Posted 2014-08-25T07:14:05.593

Reputation: 19 061

1Your 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... – Keith Randall – 2014-08-25T21:04:12.993

3@KeithRandall Oops. Let's add four bytes to make descending sequences take an unusually short amount of time, further reinforcing your belief. – Geobits – 2014-08-25T21:45:27.093

4

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.

Maarten Baert

Posted 2014-08-25T07:14:05.593

Reputation: 41

Discrete logarithms are a lot harder that I thought. My cracker has been at this for 26 hours. I give up. – Dennis – 2014-08-27T04:28:01.743

You could solve the sign problem by initializing c=1, computing c=(c<<32)+d and changing the constant accordingly. – Dennis – 2014-08-27T17:44:05.163

4

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;
}

Geobits

Posted 2014-08-25T07:14:05.593

Reputation: 19 061

28675309? 90210? – Malachi – 2014-08-26T20:46:42.923

1@Malachi Two outstanding references, no doubt, but I can neither confirm nor deny their applicability to this exercise. – Geobits – 2014-08-26T21:09:56.850

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. – Malachi – 2014-08-26T21:36:01.760

1Initial term is -8675309, delta is 5551212. – Peter Taylor – 2014-08-27T09:36:02.993

@PeterTaylor Nicely done :) – Geobits – 2014-08-27T12:37:01.817

3

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;
}

rdans

Posted 2014-08-25T07:14:05.593

Reputation: 995

60, 3913, 7826, 11739, 15652 – Martin Ender – 2014-08-25T15:20:22.273

yep you got it :) – rdans – 2014-08-25T15:43:21.853

3

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.

histocrat

Posted 2014-08-25T07:14:05.593

Reputation: 20 600

Yep, forgot they were signed. – histocrat – 2014-08-25T16:07:41.937

2622238809,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. – Martin Ender – 2014-08-25T16:16:53.260

3

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.

Tyilo

Posted 2014-08-25T07:14:05.593

Reputation: 1 372

@MartinBüttner Improving answers to get higher score when you crack them. Smart ;P – Tyilo – 2014-08-25T18:03:41.617

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. – Martin Ender – 2014-08-25T18:09:46.180

4{58871,5592,-47687,-100966,-154245} – freddieknets – 2014-08-25T21:20:59.207

@freddieknets Not the solution I used when creating it. Didn't know that NextPrime could return negative values. How did you find it? – Tyilo – 2014-08-25T21:28:09.663

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. – freddieknets – 2014-08-25T21:31:21.290

And using the fact that the BitXor should equal 1000, you know # has to have an odd amount of odd numbers. On top of that, the function NextPrime[#]-#==n seems only to return numbers of reversed 'evenness', ie, if n=18, only odd numbers. So the list should be {odd, even, odd, even, odd}. Thus the increment should be odd. Also by the fact that the BitXor==1000, one knows that either the numbers are not that big (order of a few ten/hunderd thousands), or the increment is not that big. All this together helps to make educated guesses and less computation. – freddieknets – 2014-08-25T21:35:40.473

This is the code:

start = Table[If[NextPrime[x] - x == 31, Print[x]; x,Unevaluated@Sequence[]], {x, 0, 10000}];
start2 = Table[If[NextPrime[# - a] - # + a == 18 && NextPrime[# + a] - # - a == 6 && NextPrime[# + 2 a] - # - 2 a == 9 && NextPrime[# + 3 a] - # - 3 a == 2, Table[# + (i - 1) a, {i, 0, 4}], Unevaluated@Sequence[]], {a, -99999, 99999, 2}] & /@ start;
test = Flatten[(If[BitXor @@ #~Join~(NextPrime /@ #) == 1000, #,Unevaluated@Sequence[]] & /@ #) & /@ start2] – freddieknets – 2014-08-25T21:38:09.817

@freddieknets You have definitely won this. Could you still solve it if NextPrime was replaced by Abs@NextPrime? – Tyilo – 2014-08-25T21:52:33.510

To force me finding the key you created it with? Probably yes, although it will take more calculation time (the range needs to be widened). – freddieknets – 2014-08-25T21:57:56.163

@freddieknets I don't think you can find my original key (at least not with your current method), but I'm just curious if you could find another. – Tyilo – 2014-08-25T22:16:31.313

@MartinBüttner moved – Tyilo – 2014-08-26T23:48:29.093

3

GolfScript (116 chars)

Takes input as space-separated integers.

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

Peter Taylor

Posted 2014-08-25T07:14:05.593

Reputation: 41 901

2-51469355 -37912886 -24356417 -10799948 2756521 – Dennis – 2014-08-25T22:39:21.950

Nice work. Did you exploit the small exponent? – Peter Taylor – 2014-08-25T22:54:05.573

2

No, I factorized the modulus. Took only 13 seconds using primo's Multiple Polynomial Quadratic Sieve and PyPy.

– Dennis – 2014-08-25T23:00:04.593

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. – Peter Taylor – 2014-08-25T23:03:59.400

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... – Dennis – 2014-08-25T23:08:54.647

3

C 459 bytes

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

A note about cracking:

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.

BrainSteel

Posted 2014-08-25T07:14:05.593

Reputation: 5 132

6Solution: 6174, 48216, 90258, 132300, 174342. – Tyilo – 2014-08-25T19:32:29.067

Wow that was fast. Nice one. Bruteforced, or did you find something clever I missed? – BrainSteel – 2014-08-25T19:33:40.340

I used Mathematica's symbolic evaluation like so: https://ghostbin.com/paste/jkjpf screenshot: http://i.imgur.com/2JRo7LE.png

– Tyilo – 2014-08-25T19:36:52.933

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 :( – Geobits – 2014-08-25T19:50:40.443

@Geobits That's a surprisingly accurate guess. Should've put some more 0's on the ends of those numbers. – BrainSteel – 2014-08-25T19:53:58.210

@BrainSteel I was going to go much lower, but gave it some leeway since I didn't work it all the way through. 0xC0942 is pretty low on the whole, so I figured that if you were playing with positive numbers, a[0] had to be much lower to accommodate all those additions. – Geobits – 2014-08-25T19:57:58.947

2

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.

stokastic

Posted 2014-08-25T07:14:05.593

Reputation: 981

5This is invariant under reordering of the arguments, so it's not a valid locker. – Peter Taylor – 2014-08-25T18:26:57.803

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]. – Ilmari Karonen – 2014-08-25T19:18:08.143

Darn, yes I was just fixing my typo, during which I made a crucial mistake in my algorithm, leaving it very easy to crack :| – stokastic – 2014-08-25T19:33:43.767

Actually, finding and fixing the bug was the difficult part; given your algorithm, factoring the constant was kind of an obvious thing to try. – Ilmari Karonen – 2014-08-25T19:39:03.873

2

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}
]&

(Spaces and newlines added for readability, not counted & not needed).

Usage:

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

freddieknets

Posted 2014-08-25T07:14:05.593

Reputation: 199

1Initial term 256208, delta -5. – Peter Taylor – 2014-08-26T13:34:28.307

Dang, then still it isn't unique, as this isn't my original key. Did you bruteforce? – freddieknets – 2014-08-26T13:37:46.930

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. – Peter Taylor – 2014-08-26T13:42:57.813

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. – Peter Taylor – 2014-08-26T14:02:51.497

yes but for a arithmetic sequence -as is the required input- it was supposed to be unique. – freddieknets – 2014-08-26T20:54:20.640

The unique key is what's required to be an arithmetic sequence, not the input. That can be any sequence of five 32-bit signed ints. – Peter Taylor – 2014-08-26T20:59:54.453

I found out why your key worked as well; the list I feed to FromDigits consists of numbers bigger than 9, making the inverse step impossible to do (ie, FromDigits[{1,22,13}] gives 333, inverting this by using IntegerDigits gives {3,3,3}. There is no way to retrieve the original list. But working backwards from 1913001154 and 729783244 gives possible results to PartitionsQas well.. I should have included a 6 in the key. – freddieknets – 2014-08-26T20:59:58.480

Ah ok, my bad, you are right about the input. – freddieknets – 2014-08-26T21:01:50.253

1

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.

isaacg

Posted 2014-08-25T07:14:05.593

Reputation: 39 268

7Have you just given away that 1,2,3,4,5 is the key? – Peter Taylor – 2014-08-25T09:55:43.287

1Every input I tried returned 1, did you switch 1 and 0 as output? – Tyilo – 2014-08-25T17:27:51.807

Sorry, I didn't understand the Output vs. Return distinction - the program should work now. Same underlying algorithm. – isaacg – 2014-08-25T21:20:04.210

397,96,95,94,93 (I just killed my cracking score.) – Dennis – 2014-08-25T23:23:28.367

@Dennis Well done. The cracking score system needs to be changed - it's creating some really weird incentives. – isaacg – 2014-08-25T23:37:35.317

1

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)

Kyle Kanos

Posted 2014-08-25T07:14:05.593

Reputation: 4 270

3, 7, 11, 15, 19 or 6, 14, 22, 30, 38 – Dennis – 2014-08-26T04:50:43.700

@Dennis: sadly it is neither of those. I'll have to work on it a bit later to ensure the non-uniqueness. – Kyle Kanos – 2014-08-26T11:15:55.463

t1==0 whenver S is increasing. Also, both conditions are homogeneous; if S is a solution, so is kS. – Dennis – 2014-08-26T16:55:54.283

1

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);

hmatt1

Posted 2014-08-25T07:14:05.593

Reputation: 3 356

1

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

Vectorized

Posted 2014-08-25T07:14:05.593

Reputation: 3 486

3Initial value 781783, increment 17982811 – Peter Taylor – 2014-08-26T10:39:35.510

@PeterTaylor Argh... =) – Vectorized – 2014-08-26T10:43:38.057

1

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?

histocrat

Posted 2014-08-25T07:14:05.593

Reputation: 20 600

2309, 77347, 154385, 231423, 308461 but I don't think it's unique. – Martin Ender – 2014-08-26T14:54:12.507

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. – Martin Ender – 2014-08-26T14:58:43.467

Sorry, I guess I messed up the test string. There was supposed to be only one regexp with a unique factorization. – histocrat – 2014-08-26T15:00:42.327

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. – Martin Ender – 2014-08-26T15:02:18.227

1

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

Dennis

Posted 2014-08-25T07:14:05.593

Reputation: 196 637

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. – Peter Taylor – 2014-08-29T21:55:05.043

0

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;
}

rdans

Posted 2014-08-25T07:14:05.593

Reputation: 995

5Brute forced: 320689, 444121, 567553, 690985, 814417 – Tyilo – 2014-08-25T21:20:10.103

@Tyilo If you stop now, I think no cracker can beat your score. ;) – Martin Ender – 2014-08-25T21:48:21.527

2@MartinBüttner Unless this can be golfed to under 512 per the OP, I don't think it counts. – Geobits – 2014-08-25T22:43:36.913

0

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);}

Orby

Posted 2014-08-25T07:14:05.593

Reputation: 844

1So, 0 0 0 0 0? – Dennis – 2014-08-26T00:01:35.097

Sigh that was a bug, but yes that works. – Orby – 2014-08-26T00:06:45.260

I've updated with a corrected version that should be a little more interesting ;) – Orby – 2014-08-26T00:14:38.940

See the corrected version here.

– Orby – 2014-08-26T00:27:52.087

0

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.

nitrous

Posted 2014-08-25T07:14:05.593

Reputation: 81

0

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.

Dennis Jaheruddin

Posted 2014-08-25T07:14:05.593

Reputation: 1 848

1This approach is prohibited in the comments. If it's not mentioned in the question, propose an edit. Sorry. – Peter Taylor – 2014-08-26T10:51:25.777

@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. – Dennis Jaheruddin – 2014-08-26T10:54:16.433

0

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.

COTO

Posted 2014-08-25T07:14:05.593

Reputation: 3 701

0

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!

xnor

Posted 2014-08-25T07:14:05.593

Reputation: 115 687

0

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 *)

Tyilo

Posted 2014-08-25T07:14:05.593

Reputation: 1 372

Assuming that I've correctly understood what your code does, I get several solutions of which the smallest is initial term 9244115, delta 25. – Peter Taylor – 2014-08-27T11:39:29.317

@PeterTaylor I can confirm that that one is valid. – Martin Ender – 2014-08-27T12:12:46.967

@PeterTaylor correct, another key is 1073743739, 1073886396, 1074029053, 1074171710, 1074314367 – Tyilo – 2014-08-27T14:29:35.730

0

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

Snack

Posted 2014-08-25T07:14:05.593

Reputation: 2 142

This isn't a valid submission; it accepts the input 1,0,1,63021563418517255630720,0. – Dennis – 2014-08-27T03:01:39.260

@Dennis Fixed. I hope it's valid now. – Snack – 2014-08-27T05:03:51.717

119960211, 31167202, 42374193, 53581184, 64788175 – Dennis – 2014-08-27T05:07:18.087

@Dennis Correct and awesome. I think I'm very poor at math. – Snack – 2014-08-27T05:13:56.900

Simply checking if the sequence is in fact arithmetic (e.g., b-a==c-b==d-c==e-d) may have provided uniqueness without revealing so much information about the key. But I had already written a brute force cracker (estimated running time: 5 hours) for the original version. 63021563418517255630720 has only 256 prime factors and d has to be one of them... – Dennis – 2014-08-27T05:18:32.613

2@Dennis, 63021563418517255630720 isn't a 32-bit number. – Peter Taylor – 2014-08-27T08:59:23.377

@PeterTaylor: Good point... 274643839 40416932 26790592 8565190 0 then. – Dennis – 2014-08-27T13:16:00.013

0

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

Dennis

Posted 2014-08-25T07:14:05.593

Reputation: 196 637

1737262825 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. – Peter Taylor – 2014-08-27T22:15:34.003

@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... – Dennis – 2014-08-27T23:59:19.787

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. – Peter Taylor – 2014-08-28T07:08:30.950

1737262825 208413109 -320436607 -849286323 -1378136039 – Peter Taylor – 2014-08-28T07:27:21.537

@PeterTaylor: That's the one. I hope the 512 bit version lasts longer. – Dennis – 2014-08-28T17:37:08.997

0

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]

ElectricWarr

Posted 2014-08-25T07:14:05.593

Reputation: 309

1Pretty easy: [-481890276, -594823292, -728999970, -887503650, -1073741792] – Tyilo – 2014-08-27T09:03:36.203

Thought so, well done :) – ElectricWarr – 2014-08-27T09:05:21.950

-2

C, 212 (Cracked)

This is the same idea as my previous submission, golfed more thoroughly, with a bug corrected that passed 0,0,0,0,0 (Thanks to Dennis for pointing out the bug). Compile with -std=c99.

#define L long long
p(L x){x=abs(x);for(L i=2;i<x;i++){if((x/i)*i==x)return 0;}return(x>1);}
f(a,b,c,d,e){char k[99];L 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);}

Orby

Posted 2014-08-25T07:14:05.593

Reputation: 844

Any sequence (arithmetic or not) of negative primes will work. Two examples: -7 -37 -67 -97 -127, -157 -127 -97 -67 -37 – Dennis – 2014-08-26T01:27:14.497

Yeah, my code is just riddled with bugs. The answer nitrous gave is along the lines of what I was looking for. But nice job pointing out the more obvious answers.

– Orby – 2014-08-26T01:32:25.100

-2

Python 3 (152)

Edit 2: I'm withdrawing this entry because it accepting the correct key seems to depend on hardware or version specifics, which would be unfair to crackers. On online Python 3 interpreters I tried, low-significance bits of the result differed slightly, suggesting the algorithm is sensitive to the exact hardware implementation of arithmetic.

Edit: Made a much longer target to make uniqueness likely given 160 bits of input. Unfortunately, now this target takes over half my characters. This means that this style of submission is unfortunately largely a compression contest.

def f(l,a=[0]):
 for n in l:a+=[(.8+.6j)**(n+a[-1])]
 return a[2::2]==[-0.20857691594748845+0.9907381787645837j,-0.7480510203178323-0.0856921111325014j]

Nothing systematic, just some annoying mangling with complex exponents.

xnor

Posted 2014-08-25T07:14:05.593

Reputation: 115 687

2Are you sure this is unique? Your hash has less than 64 bits, and the input has 160. – Martin Ender – 2014-08-26T17:49:21.683

@MartinBüttner Oh, I see. Is it actually 160 bits or 64-lg(5)? I had understood that only arithmetic sequences needed to be considered. – xnor – 2014-08-26T18:19:20.130

No, your program needs to return 0 for everything that's not an arithmetic sequence. – Martin Ender – 2014-08-26T19:15:10.620