Compare commits

..

10 Commits

Author SHA1 Message Date
63561f368e add command line parameter for name 2025-09-13 00:30:02 +02:00
49d6fdff9d fully automate 08_revisit_everything 2025-09-13 00:12:17 +02:00
f5d3828cb4 solve 08 2025-09-12 23:58:16 +02:00
997efb0ad4 improve performance of challenge 03 by precomputing giant steps 2025-09-12 17:01:56 +02:00
7f33c43169 add challenge scripts 2025-09-12 11:20:36 +02:00
81fea4865e add 08_revisit_everything.rs 2025-09-12 09:28:22 +02:00
eea37dcd31 solve all previous levels 2025-09-12 01:26:50 +02:00
1a3f5bb015 solve 07 2025-09-11 20:23:37 +02:00
2ed82171af stuff 2025-09-11 19:50:46 +02:00
02f3bfffce make it faster yet 2025-09-11 15:37:37 +02:00
28 changed files with 1256 additions and 1398 deletions

View File

@@ -11,6 +11,8 @@ reqwest = { version = "0.12.23", features = ["blocking"] }
rug = "1.28.0" rug = "1.28.0"
rand = "0.9.2" rand = "0.9.2"
tqdm = "0.8.0" tqdm = "0.8.0"
sha2 = "0.10.9"
percent-encoding = "2.3.2"
[lib] [lib]
name = "lib" name = "lib"

7
js/01_welcome.js Normal file
View File

@@ -0,0 +1,7 @@
function onClick() {
if(n >= 10000n) {
return;
}
n++;
x = n % 7n;
}

View File

@@ -0,0 +1,21 @@
const m = 14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923n;
let h;
async function prepare() {
if(n == 10000n) {
h = await sha256(name);
}
}
function onClick() {
if(n >= 20000n) {
return;
}
if(n == 10000n) {
x += h;
}
n++;
for(let i = 0; i < 100; i++) {
x = pow(x, 65537n, m);
}
}

View File

@@ -0,0 +1,33 @@
const p = 12345679943n;
function onClick() {
if(n >= 30000n) {
return;
}
n++;
x = log(42n, 1n + (x+n) % (p-1n), p);
}
function log(g, b, m) {
const s = Math.ceil(Number(m)**.5);
const r = new Map();
let a = b % m;
if(a == 1n) {
return 0n;
}
for(let i = 0; i < s; i++) {
r.set(a, i);
a *= g;
a %= m;
}
const gs = pow(g, BigInt(s), m);
a = gs;
for(let j = 1; j <= s; j++) {
const i = r.get(a);
if(i !== undefined) {
return BigInt(j*s-i);
}
a *= gs;
a %= m;
}
}

View File

@@ -0,0 +1,10 @@
function onClick() {
if(n >= 10n**8n) {
return;
}
n++;
for(let i = 0; i < 10000; i++) {
x += 41n;
x ^= 42n;
}
}

11
js/05_what_the_bf.js Normal file
View File

@@ -0,0 +1,11 @@
const f = ((ο)=>((o)=>o(((o(((ο*o([!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]))+[])[(![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]](-[+!+[]]+[!+[]+!+[]]))*o([+!+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]-([+!+[]]+[+!+[]]))+o([+!+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]+[+[]]-+!+[]))+[])[(![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]](+[],-[+!+[]]+[!+[]+!+[]])))(BigInt));
function onClick() {
if(n >= 10n**12n) {
return;
}
n++;
for(let i = 0; i < 100; i++) {
x = f(x);
}
}

View File

@@ -0,0 +1,14 @@
const m = 14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923n;
function onClick() {
if(n >= 10n**16n) {
return;
}
n++;
const a = pow(n, 65537n, m);
if(a % 1466928606874115117499939299261n == 49119078231137394008451554322n) {
x += x;
}
x += a;
x %= m;
}

View File

@@ -0,0 +1,15 @@
let f;
async function prepare() {
const get = fetch('07_weird_assembly_machine.wasm');
const obj = await WebAssembly.instantiateStreaming(get);
f = obj.instance.exports.f;
}
function onClick() {
if(n >= 10n**18n) {
return;
}
n++;
x = BigInt.asUintN(64, f(x, n));
}

Binary file not shown.

View File

@@ -0,0 +1,59 @@
const m = [
1434008120931012805118743381511953470053626771934922366720474361817092344508461315782084314493561729943207476618986862630642339876124303277669871276872966561372584096756184146218943438497504108129008248947186295903702650936563195517405177267n,
2279983661166952569412337967792106681853682761140508555222469060830820310854240357968620360297575902950280777825697828457195462861233847516393870602678279643129330544204145040751369969379909048248974150190225328726111083312867874886821021103n,
2403618920217682814630057320815015451780244245370783386150600183266752801851444036459202928614238339117073052233115617730895326577436837775969446809467396763885076993639257102975158794586432834588823770619549927566204909745661463923650207527n,
2211546667714470043261801539278553165605603776798179390251801872528197206642136833266100994696226928008915728096531663182964211466279822828133246114741263620898853542511659005977098742505685248155022513107926722707345462354618444663133511693n,
5010303295979029720953954773805463848657367496896667256925387074631207128976445011411567186128665343367664557600927865746013809617850756247038364977849593298370638415538050617717579812040063809050466079467593876757904967054587247239775981173n,
3643715306191323974849750185026376664803002052031009917919146298629124228139669830885418351414368670190933608901908463160313491829979902265661425377942098542786579385118688686530379428281500432090209857512031899193610942009997666480141622931n,
4241834355731759088612098900889150480486830356437779625635656124158632786788891567665015370346587717023382467402755844902551269466840016945251052520143748217810459016980596787260934741544681783243577436529017346762263051435128563504848147047n,
2523900322512898153092283527555686191954886966926984043710614987380057039954266050243558368595618000310491183390298731322739555708825633335455707335046252155477145429505231996976303780687577721717937956727462248609588253109048826912219512233n,
1171824891807552748899024459763353345756465570610286429518292854539955442689370561445213645478177496112486904608544314008088766463602198222556565269084818799872887643847609538261074418353385510616209919715913997563223016102524218731609073989n,
46143420546617745197213974992864349706110841054938173439888506485894731816049443533063388738883948066474775508317079165731544093393852672679526902040341664165103617856112836137307481490757786503309809660177211850194917302104601047445901953n,
752940078968697502678967384415617976772053933529596207932495368245135279916303315035371282640886295210962243111798224672106391175631921911566406669776741217206089188001565916873143077167066022880702036063882903129906642676129495022972131209n,
1520329335648026567766367275046307578542257991128853001791455552493665632232325588405913221176897049790060536801309884790312144713538875231774340342847186215385917144874277668809985499482994078141272859278475075285977463657736734963652987373n,
50017625495288818782435924507013834110031999034643307338382821405698791610778877531830614693405608386655072058895222505909833754916862533905752631274852366748935792253442598350951461591550736346237955863906449458952663228800927140320157667n,
38401610206931167080264498597398870802860254093725730772991011582569894725813373580324866968569176388369611982707097825344506655231925447764442769351345178318652542550409150557352343943618674608946011463309394821673565650165744273097849949n,
184608244646942021323366304782439538668746375277959348413634650687235587234614717772753935753287722857766192563391263109670280253185426161046298354787439672044497169888140233752555779424149969713422475505388807903963252621863734032956280519n,
351257593287654452522276916291373563742090233637383104641821340906564637280571336214002417682603763101501053115051814027840290224795605063148356403544846161606884919930269677277921998672949839936317112237896436966630449023178621753921263019n,
17776213033029898042736097216007742758258673720676143715791913350512342764629944960235747926785035898455679245982654344139524841812891998487061291841045102881105147645119091822393445581339563032411679270141022474438218196237858872902098301n,
1119968749281206669187118962426182039471518541839452651714133200569385292395928211155932154512551823867768143506831179697150725335729082336884390018097450391780455129434304717766108240883676474188676687895688014005390129134060293445952714131n,
2380359028703143565637146811469828781458088476878403649995644924026273963767396041207843943179863650694243979825010501084343724584937371440937331372027478732522369607122724766608383356158192256503987385487068417019456480384653228271517184073n,
936391425922485612330507260988001138454208806035318063315033628148710609664547188763477146808759892616317103092432173093713978381604382096301822456981993396860893433866194478210978043268587964153688806562028136539787248761208718402921714823n,
2391922140661526942794958081614866503484666510987906109575239558478076826463675970540222364377429236018134610321177838404492145979186686367103845387306040811399772932134010203596245485657848849575365830819533003431899529331962049972105422829n,
964374520562152761892099701871246383149820707812540579294812519029773619714236033304961754196611532652288982150226191973613367922123899620952613834335606606286016170579235167587934724407287026718339208674781371124584567946455593866472142439n,
661248789387918195968343456268415015655227429901485551376733649662534559008900836450733880455467249525009566343824739697592753526891306540092946639656510220832776564628364080959055214446202095345118415029995831071367289505624996230686042743n,
1495554819407996415862156847203243369888937825574835272994697401723776375381219545680004526750874917248129621701075619516487125846492717688083196840105055779039883420765261872964729328338142922514236283019345885773272705802789375709371531891n,
2050623645029219438127819922659780851370739111321093329697282080391534071710675160727304612357988694773734599338417354100409517400415116108045288729878347023871908849359856487326222636295170968226843328973460491743192554642495605580203827647n,
5300307462410213577667480837938258777512352583051978520467068441893175668391866168747583454129771867041290645051627565118578602725370687799533406736037648231124221590788082333656018605599589489800640114935804161182962684573894987008279375881n,
3704327655413180273494896105414341120264540967426618385392149993686601012341448146813701061680592497964083943234912731844161335477856719778925685202496984827468326099066276955751929212099287128630393090960611662156345752418189491108549779761n,
4293873523905537531247339274016468845613818921758414861106911431522285730431627111776083755372250902094439575944006556178967448926801694819806680902651676479412361255593771594300163105918014188734865473316383051363586442734877422424944476487n,
1589457356017416267968030208391225107392251829332800185708809994594071680629191862623870630995580949827174233852065931316179886989972734453310743029959684374385051032958116409820646011612627461794497048612013500205304829106740521813279065839n,
677060499756811014115027316973737658993937681267671378751091515074444191639222306675859985253758266662687011882335084637681850124628916282787941181661248429412152192230660554583653075199720096784977912362093898785710927643429800554309996621n,
4556683258594822402855414380362620295231673046713752880933967889771646856051745784462468117575177892006513392693685616569935833357648393898915677206732580748330214938398411668157941515847730087263301030154072458063812554524260405671629754999n,
1602074580348123931489241137005511885150980182400049992026659585131187985620536794154659820191316264063547338262596211651955802983450000900446591221580949545163434870046188079786417621515405352023176920247457687361358148356208096808525338397n,
2561993755606565068035375148802286812072711717323441363005149722023895797027723216764951149251447180880317275019544062589806987036712157902709291674934493635207098007981128987753281766285445399631018190456476459604899786219806829862034503919n,
1457054801380350736800076081677201400665406203824020727471775641174383980331187058211832905604880205627938232136048301389594977658775329490376467311636742994730009572046684919498881836580821362806591224089188354188782107744327550013385898679n,
63236406531205434317594389945524553066650347945711034187542626293222184231786980314347573971609802315464270916666042219689326463061892323637662557342398379414478296594450374661462435994098294952191568682470529143295022566680404002417824407n,
197584207289801721640320350702781512605131263686515431131918340568997783498811538104924263177220361290500812540231048642224996620094592927292942263102162109623392197130698355962984228640696217934383302653006588137949636000986800801778335657n,
107646974355805618130192750841008263946998235997036512644246089806483971253986128403392278299190598483359268422291624377225409658571257936659998943160556099228016404911568061972541462863973742808216138653302666989981023076627131009019648093n,
1339338638103691041488101095975795624888087363910833767941545495164307897693922886889431835980515628174298063795556722365483994582432076986194090322659335982083818451837412988740007497627907154682332316972997765904572884621671832534078952307n,
4434008847683596023521080910694307462609680232648893208331172489192536036999251664058651161016448705529504803145115341661351913895515662510503514243928030586139092055076376059786525834604160882940981043706619590945099008097035756330871176929n,
2861034394438211841574954026003099819138101239247590122220350015475642835378420417008259980687528330087930738069620032709655292858712710050922359392413494086067180601383341612168193292772028605966992134213209023470256124404157207490432001519n,
2192496740130688243467014868961425982524426805724142867736885035473886629020046845749143690992453345556925544037271383038390660805714030629830845497904446979103911346917405936472233104694103049940390437540539269358666128436739707024829933171n,
4729254672091433598483706976591610165407510022326154887172965802144851945337220063633854456109688411742113721031379206359782182729020553179365019549633309936476652959201812418790254033614677768930428905990768941807243900642422321011756634063n
];
function onClick() {
if(n >= 10n**20n) {
return;
}
n++;
const w = x % 42n;
let y = x / 42n;
for(let i = 0; i < 100; i++) {
y = pow(y, 65537n, m[w]);
}
x = 42n * y + w;
}
/* Lbh pna punatr gur pbybe bs lbhe anzr jvgubhg punatvat lbhe anzr. */

151
js/common_v=2.js Normal file
View File

@@ -0,0 +1,151 @@
/*
NOTE: this just contains user interface logic;
there is probably not much interesting stuff here
*/
let name, n, x, n_old, n_last;
async function init() {
const params = (new URL(document.URL)).searchParams;
if(params.has('name')) {
name = params.get('name');
} else {
/* missing name, redirect to start screen */
location.replace('.');
return;
}
/* people can do more than 2^53 button clicks, so we need big integers */
if(params.has('n') && params.has('x')) {
n = BigInt(params.get('n'));
x = BigInt(params.get('x'));
} else {
n = 0n;
x = 0n;
}
n_old = 0n;
n_last = -1n;
if(typeof prepare == 'function') {
await prepare();
}
const button = document.querySelector('button');
button.textContent = n;
button.addEventListener('click', onClick);
setInterval(() => {
if(n > n_last) {
/* to spare the browser, we do this at most 10 times per second */
const params = new URLSearchParams({name, n, x});
history.replaceState(null, '', '?' + params);
button.textContent = n;
n_last = n;
}
}, 100);
communicate();
}
document.addEventListener('DOMContentLoaded', init);
async function communicate() {
const error = document.querySelector('#error');
try {
/* only submit increased click counts, otherwise just fetch scores */
const path = 'server.php' + ((n_last > n_old) ? location.search : '');
const result = await fetch(path);
if(!result.ok) {
throw new Error(`${result.status} ${result.statusText}`);
}
if(n_last > n_old) {
n_old = n_last;
}
const json = await result.json();
if(json.flag && !location.pathname.endsWith('/' + json.flag)) {
/* advance to next level */
location.replace(json.flag + location.search);
return;
}
if(json.scores) {
displayScores(json.scores, json.time);
}
if(json.error) {
throw new Error(json.error);
}
const timeStr = new Date(json.time * 1000).toLocaleTimeString('de-DE');
error.textContent = `Zuletzt aktualisiert: ${timeStr}`;
} catch(e) {
console.warn(e);
error.textContent = e;
}
setTimeout(communicate, 1000);
}
function displayScores(scores, time) {
const table = document.querySelector('table');
while(table.rows.length > 1) {
table.deleteRow(-1);
}
scores.sort((a, b) => {
const n_a = BigInt(a.n);
const n_b = BigInt(b.n);
if(n_a > n_b) {
return -1;
}
if(n_a < n_b) {
return 1;
}
if(a.time < b.time) {
return -1;
}
if(a.time > b.time) {
return 1;
}
return 0;
});
scores.forEach((entry) => {
const row = table.insertRow();
const nameCell = row.insertCell();
/* protect against unicode bidi control characters */
const bdi = document.createElement('bdi');
bdi.textContent = entry.name;
nameCell.appendChild(bdi);
nameCell.title = entry.name;
const timeCell = row.insertCell();
const date = new Date(entry.time * 1000);
if(time - entry.time < 86400) {
timeCell.textContent = date.toLocaleTimeString('de-DE');
} else {
timeCell.textContent = date.toLocaleDateString('de-DE');
}
timeCell.title = date.toLocaleString('de-DE');
const nCell = row.insertCell();
nCell.textContent = entry.n;
nCell.title = entry.n;
});
}
/* compute SHA-256 digest represented as integer (big endian) */
async function sha256(str) {
const msg = new TextEncoder().encode(str);
const buffer = await crypto.subtle.digest('SHA-256', msg);
const bytes = new Uint8Array(buffer);
let val = 0n;
for(const b of bytes) {
val = (val << 8n) | BigInt(b);
}
return val;
}
/* compute a^k modulo m */
function pow(a, k, m) {
let b = 1n;
for(; k; k >>= 1n) {
if(k & 1n) {
b *= a;
b %= m;
}
a *= a;
a %= m;
}
return b;
}

BIN
res/03_baby_steps.bin Normal file

Binary file not shown.

BIN
res/03_giant_steps.bin Normal file

Binary file not shown.

View File

@@ -0,0 +1,256 @@
6563504930575804778
3177554099846544556
14859870375767071104
2361978668621667923
3143167595286206242
14095566306004759633
6896557042998150768
4462024892233517220
6694476164706603992
4101034334834323206
16919437506981809216
7555882741782405923
2628576702768829495
9893623336811473734
321448934705618219
10658829649099122152
2041445642416509779
10219048753829035159
16805862748866069158
10040916278977753989
6307216144763488332
7556799640693587259
10364880594488944589
4148363280372604554
10843489283249915473
10941839320982089921
12200589183353651648
13289846021634563271
9908808602666874083
11200096838332863267
8779557412750126267
8653500638442577520
5278382863123262139
5783872159081604742
8125287062915914468
2242536959895356377
4005886220233485538
16562333581271451717
1417622956358486028
17949254327843118224
11638382071724344512
1599533962231322857
3108365940793816305
4242306746708662266
4952142584625629079
8415262979453050616
17056549971761457216
3044401595350323209
9932836459025874446
17683019803052515221
2433910229198456491
11984404922749323692
5524563739374899072
18259777400123222730
4011842113907150331
13821416711910403019
6047075845099054027
15787995709438817819
15586362769001272194
9547178878896838664
7095984364360639673
11886247752272930995
9985144182130335662
13251170938278484486
4652450378788876572
1718813027742122072
663918887826880444
6670740316248663863
6700009143044041388
16923466181555045374
11387212886131952048
13965979168082782709
2422236213071595233
4699138634002865087
6493539149331166441
7518901355855126514
16145558963603531461
14786024152105552650
6994957500730603671
6969343254888557997
13840983121869895238
13660562997364925760
17265722274403090344
16718136092983418592
4687774949942350684
1375392036798645113
2003687933393780368
10165815540082234487
6089981897628107340
14541747794483572236
10203690416684845063
3215632556062991790
5425642782789424861
13599224699425799085
12514386124935070361
8663785549291965158
16808180269220250739
958315213891692337
17602667895639479950
1575696692466204467
17915906007703271560
14748722093156428888
1657002993440401555
661824732220019475
4209888120689731341
16768316015744524190
4243337273520801682
2339349826505601295
3824297886017649294
12702982826142705690
16612576840497393302
14651413872459783243
1731111914295200492
7107419468395208292
13131631592659790069
7650600002594848965
10405567400049055611
8308615406494459745
3539740125465153737
5461340322324117263
3781913427618838536
15971526239448286573
14866630059533000065
9057464874518875466
12416130366361631938
16536231451954324990
16940792417174466635
5850876492391527467
8409677954752892479
14645542356465944448
222773118531975189
8843321651534853339
18155004654525928367
874144551332925702
13029240668713846903
10134094171892588961
14847849150997407724
15268365766299545880
12681437973300849606
9073037709094073235
5903235897841107084
13454671887999382224
1858835333224639960
9249476666791031049
4223733763389771996
15384221398063151306
10517318028043688548
14460943107538037335
5154513940699923775
1487808311209105759
10531814582629388228
13949079608223777930
7235144852537941787
15896454296269928651
17639234901395308799
3843116287193798732
13850621202730186058
14394021663790134434
5156903507008819810
8215065870912194262
4311375377346268620
10171989316456362870
163589086269419441
3851905914730271938
15334437853140690383
15539559255153964902
16896869453263295473
5093215075951161381
11973288268634380358
5063471141738823749
14989360565903092894
14383904172638615636
16726778109629071291
8426599513938923802
10135704539862093112
10650096844272335586
11665119603940578625
16874279119083921534
5506586508252141218
12933308300960365793
5248411009075909495
2258335812944206660
8597559794487195679
7377768646895780754
3492695033858227458
10967074645264403701
4191289746488745512
10814396656746439511
7977751296373368968
7365044695914860944
719961330644640786
9787541545720428689
15604445254264824171
2390604585013608559
11986374754145330532
11017949026101828516
12566345980261789685
15356854551478336603
7512099414187555837
12750275831668325946
10214055675311439170
13443646811679848535
16700058242611721938
4423454089307812290
9103802734880117173
2844597800879830746
13843180097957768889
8451963189055726564
3487238693652813426
1299546876649551534
12113986972185246713
6519448239293388674
15121003074094999781
14734970561277902445
14188671603580717908
6990763574012814336
10826116378520780499
12743257710490956107
10544515943049329704
7398185314804331323
17207979707505274370
10312488623848443780
2525681217825377635
1209032913852334193
2466271244689038797
11480020761807728949
9382271556984549762
11547951404763329175
6098523488344631739
13976835011142976617
5952967173673330791
10742137247908568911
17711990646608869291
614357866529740908
9459271394207301277
13255507779934222511
4405075157125241953
2658215311620786269
3438348388076752545
11273337813277990213
6461206275074180061
407462859018947407
16015082222849827426
15274784353409233905
10868734442868526034
15301879674491522395
15304647555608021557
1004732939015301729
14098615156664030434
11650248670150490593
15906967279319496936
531379790791487398
11796026101712826135
2668163399826034890
1114227485540495868
12046048025420064663

View File

@@ -0,0 +1,42 @@
F = GF(2)
R.<x> = PolynomialRing(F)
S.<xi> = R.quotient_ring(x^64 + 1)
T.<X> = PolynomialRing(S)
Ti.<Xi> = T.quotient_ring(X^64 + 1)
Tj.<Xj> = T.quotient_ring(X^64)
def num_to_poly(num):
out = 0
i = 0
while num != 0:
if num % 2 == 1:
out += xi^i
i += 1
num //= 2
return out
def poly_to_num(poly):
out = 0
for i in range(0, 64):
if poly[i] == 1:
out |= 1 << i
return out
with open("./07_weird_assembly_machine.data") as f:
data = [int(line) for line in f.readlines() if line]
f = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[:128]])
g = reduce(lambda a, b: a * X + b, [num_to_poly(a) for a in data[128:]])
fg = f(g)
fgi = Ti([fg[i] for i in range(0, fg.degree())])
fgj = Tj([fg[i] for i in range(0, fg.degree())])
print("\n\n======= f(g(x)) =======")
for i in reversed(range(0, 64)):
print(poly_to_num(fgi.lift()[i]))
print("\n\n======= f(g(x)) =======")
for i in reversed(range(0, 64)):
print(poly_to_num(fgj.lift()[i]))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
#![allow(dead_code)]
// You can change the color of your name without changing your name.
use lazy_static::lazy_static;
use lib::submit_with_name;
use rug::ops::{DivRounding, Pow};
use rug::Integer;
use std::str::FromStr;
lazy_static!(
static ref M: Vec<Integer> = vec![
Integer::from_str("1434008120931012805118743381511953470053626771934922366720474361817092344508461315782084314493561729943207476618986862630642339876124303277669871276872966561372584096756184146218943438497504108129008248947186295903702650936563195517405177267").unwrap(),
Integer::from_str("2279983661166952569412337967792106681853682761140508555222469060830820310854240357968620360297575902950280777825697828457195462861233847516393870602678279643129330544204145040751369969379909048248974150190225328726111083312867874886821021103").unwrap(),
Integer::from_str("2403618920217682814630057320815015451780244245370783386150600183266752801851444036459202928614238339117073052233115617730895326577436837775969446809467396763885076993639257102975158794586432834588823770619549927566204909745661463923650207527").unwrap(),
Integer::from_str("2211546667714470043261801539278553165605603776798179390251801872528197206642136833266100994696226928008915728096531663182964211466279822828133246114741263620898853542511659005977098742505685248155022513107926722707345462354618444663133511693").unwrap(),
Integer::from_str("5010303295979029720953954773805463848657367496896667256925387074631207128976445011411567186128665343367664557600927865746013809617850756247038364977849593298370638415538050617717579812040063809050466079467593876757904967054587247239775981173").unwrap(),
Integer::from_str("3643715306191323974849750185026376664803002052031009917919146298629124228139669830885418351414368670190933608901908463160313491829979902265661425377942098542786579385118688686530379428281500432090209857512031899193610942009997666480141622931").unwrap(),
Integer::from_str("4241834355731759088612098900889150480486830356437779625635656124158632786788891567665015370346587717023382467402755844902551269466840016945251052520143748217810459016980596787260934741544681783243577436529017346762263051435128563504848147047").unwrap(),
Integer::from_str("2523900322512898153092283527555686191954886966926984043710614987380057039954266050243558368595618000310491183390298731322739555708825633335455707335046252155477145429505231996976303780687577721717937956727462248609588253109048826912219512233").unwrap(),
Integer::from_str("1171824891807552748899024459763353345756465570610286429518292854539955442689370561445213645478177496112486904608544314008088766463602198222556565269084818799872887643847609538261074418353385510616209919715913997563223016102524218731609073989").unwrap(),
Integer::from_str("46143420546617745197213974992864349706110841054938173439888506485894731816049443533063388738883948066474775508317079165731544093393852672679526902040341664165103617856112836137307481490757786503309809660177211850194917302104601047445901953").unwrap(),
Integer::from_str("752940078968697502678967384415617976772053933529596207932495368245135279916303315035371282640886295210962243111798224672106391175631921911566406669776741217206089188001565916873143077167066022880702036063882903129906642676129495022972131209").unwrap(),
Integer::from_str("1520329335648026567766367275046307578542257991128853001791455552493665632232325588405913221176897049790060536801309884790312144713538875231774340342847186215385917144874277668809985499482994078141272859278475075285977463657736734963652987373").unwrap(),
Integer::from_str("50017625495288818782435924507013834110031999034643307338382821405698791610778877531830614693405608386655072058895222505909833754916862533905752631274852366748935792253442598350951461591550736346237955863906449458952663228800927140320157667").unwrap(),
Integer::from_str("38401610206931167080264498597398870802860254093725730772991011582569894725813373580324866968569176388369611982707097825344506655231925447764442769351345178318652542550409150557352343943618674608946011463309394821673565650165744273097849949").unwrap(),
Integer::from_str("184608244646942021323366304782439538668746375277959348413634650687235587234614717772753935753287722857766192563391263109670280253185426161046298354787439672044497169888140233752555779424149969713422475505388807903963252621863734032956280519").unwrap(),
Integer::from_str("351257593287654452522276916291373563742090233637383104641821340906564637280571336214002417682603763101501053115051814027840290224795605063148356403544846161606884919930269677277921998672949839936317112237896436966630449023178621753921263019").unwrap(),
Integer::from_str("17776213033029898042736097216007742758258673720676143715791913350512342764629944960235747926785035898455679245982654344139524841812891998487061291841045102881105147645119091822393445581339563032411679270141022474438218196237858872902098301").unwrap(),
Integer::from_str("1119968749281206669187118962426182039471518541839452651714133200569385292395928211155932154512551823867768143506831179697150725335729082336884390018097450391780455129434304717766108240883676474188676687895688014005390129134060293445952714131").unwrap(),
Integer::from_str("2380359028703143565637146811469828781458088476878403649995644924026273963767396041207843943179863650694243979825010501084343724584937371440937331372027478732522369607122724766608383356158192256503987385487068417019456480384653228271517184073").unwrap(),
Integer::from_str("936391425922485612330507260988001138454208806035318063315033628148710609664547188763477146808759892616317103092432173093713978381604382096301822456981993396860893433866194478210978043268587964153688806562028136539787248761208718402921714823").unwrap(),
Integer::from_str("2391922140661526942794958081614866503484666510987906109575239558478076826463675970540222364377429236018134610321177838404492145979186686367103845387306040811399772932134010203596245485657848849575365830819533003431899529331962049972105422829").unwrap(),
Integer::from_str("964374520562152761892099701871246383149820707812540579294812519029773619714236033304961754196611532652288982150226191973613367922123899620952613834335606606286016170579235167587934724407287026718339208674781371124584567946455593866472142439").unwrap(),
Integer::from_str("661248789387918195968343456268415015655227429901485551376733649662534559008900836450733880455467249525009566343824739697592753526891306540092946639656510220832776564628364080959055214446202095345118415029995831071367289505624996230686042743").unwrap(),
Integer::from_str("1495554819407996415862156847203243369888937825574835272994697401723776375381219545680004526750874917248129621701075619516487125846492717688083196840105055779039883420765261872964729328338142922514236283019345885773272705802789375709371531891").unwrap(),
Integer::from_str("2050623645029219438127819922659780851370739111321093329697282080391534071710675160727304612357988694773734599338417354100409517400415116108045288729878347023871908849359856487326222636295170968226843328973460491743192554642495605580203827647").unwrap(),
Integer::from_str("5300307462410213577667480837938258777512352583051978520467068441893175668391866168747583454129771867041290645051627565118578602725370687799533406736037648231124221590788082333656018605599589489800640114935804161182962684573894987008279375881").unwrap(),
Integer::from_str("3704327655413180273494896105414341120264540967426618385392149993686601012341448146813701061680592497964083943234912731844161335477856719778925685202496984827468326099066276955751929212099287128630393090960611662156345752418189491108549779761").unwrap(),
Integer::from_str("4293873523905537531247339274016468845613818921758414861106911431522285730431627111776083755372250902094439575944006556178967448926801694819806680902651676479412361255593771594300163105918014188734865473316383051363586442734877422424944476487").unwrap(),
Integer::from_str("1589457356017416267968030208391225107392251829332800185708809994594071680629191862623870630995580949827174233852065931316179886989972734453310743029959684374385051032958116409820646011612627461794497048612013500205304829106740521813279065839").unwrap(),
Integer::from_str("677060499756811014115027316973737658993937681267671378751091515074444191639222306675859985253758266662687011882335084637681850124628916282787941181661248429412152192230660554583653075199720096784977912362093898785710927643429800554309996621").unwrap(),
Integer::from_str("4556683258594822402855414380362620295231673046713752880933967889771646856051745784462468117575177892006513392693685616569935833357648393898915677206732580748330214938398411668157941515847730087263301030154072458063812554524260405671629754999").unwrap(),
Integer::from_str("1602074580348123931489241137005511885150980182400049992026659585131187985620536794154659820191316264063547338262596211651955802983450000900446591221580949545163434870046188079786417621515405352023176920247457687361358148356208096808525338397").unwrap(),
Integer::from_str("2561993755606565068035375148802286812072711717323441363005149722023895797027723216764951149251447180880317275019544062589806987036712157902709291674934493635207098007981128987753281766285445399631018190456476459604899786219806829862034503919").unwrap(),
Integer::from_str("1457054801380350736800076081677201400665406203824020727471775641174383980331187058211832905604880205627938232136048301389594977658775329490376467311636742994730009572046684919498881836580821362806591224089188354188782107744327550013385898679").unwrap(),
Integer::from_str("63236406531205434317594389945524553066650347945711034187542626293222184231786980314347573971609802315464270916666042219689326463061892323637662557342398379414478296594450374661462435994098294952191568682470529143295022566680404002417824407").unwrap(),
Integer::from_str("197584207289801721640320350702781512605131263686515431131918340568997783498811538104924263177220361290500812540231048642224996620094592927292942263102162109623392197130698355962984228640696217934383302653006588137949636000986800801778335657").unwrap(),
Integer::from_str("107646974355805618130192750841008263946998235997036512644246089806483971253986128403392278299190598483359268422291624377225409658571257936659998943160556099228016404911568061972541462863973742808216138653302666989981023076627131009019648093").unwrap(),
Integer::from_str("1339338638103691041488101095975795624888087363910833767941545495164307897693922886889431835980515628174298063795556722365483994582432076986194090322659335982083818451837412988740007497627907154682332316972997765904572884621671832534078952307").unwrap(),
Integer::from_str("4434008847683596023521080910694307462609680232648893208331172489192536036999251664058651161016448705529504803145115341661351913895515662510503514243928030586139092055076376059786525834604160882940981043706619590945099008097035756330871176929").unwrap(),
Integer::from_str("2861034394438211841574954026003099819138101239247590122220350015475642835378420417008259980687528330087930738069620032709655292858712710050922359392413494086067180601383341612168193292772028605966992134213209023470256124404157207490432001519").unwrap(),
Integer::from_str("2192496740130688243467014868961425982524426805724142867736885035473886629020046845749143690992453345556925544037271383038390660805714030629830845497904446979103911346917405936472233104694103049940390437540539269358666128436739707024829933171").unwrap(),
Integer::from_str("4729254672091433598483706976591610165407510022326154887172965802144851945337220063633854456109688411742113721031379206359782182729020553179365019549633309936476652959201812418790254033614677768930428905990768941807243900642422321011756634063").unwrap(),
];
static ref E: Integer = Integer::from(65537);
static ref E_100: Integer = Integer::from(65537).pow(100);
static ref E_1000: Integer = Integer::from(65537).pow(1000);
static ref P: Integer = Integer::from_str("2134638905903015345595412931439525422327695207079839833349799642610037970639957457078422305821013930668706217301787851463").unwrap();
static ref Q: Integer = Integer::from_str("2134638905903015345595412931439525422327695207079839833349799642610037970639957457078422305821013930668706217301787851473").unwrap();
static ref PHI: Integer = Integer::from_str("4556683258594822402855414380362620295231673046713752880933967889771646856051745784462468117575177892006513392693685616565666555545842363207724851343853529903674824524238732001458342230627654145983386115997227846421784693186847971068054052064").unwrap();
);
const LIMIT: u128 = 100_000_000_000_000_000_000;
const NAME: &str = " Jonah";
const N: u128 = 1000000000000000000;
const X: &str = "3595876711108608978";
fn main() {
assert_eq!(M[30].clone(), P.clone() * Q.clone());
assert_eq!(PHI.clone(), (P.clone() - 1) * (Q.clone() - 1));
let truth = Integer::from(42);
let k = Integer::from(LIMIT - N) * 100;
let e = E.clone().pow_mod(&k, &PHI).unwrap();
let x = Integer::from_str(X).unwrap();
let w: usize = x.clone().modulo(&truth).try_into().unwrap();
assert_eq!(w, 30);
let mut y = x.clone().div_floor(&truth);
y = y.pow_mod(&e, &M[30]).unwrap();
let x: Integer = y * 42 + w;
println!("x = {x}\nn = {LIMIT}");
submit_with_name(NAME, LIMIT, x).unwrap();
}

69
src/bin/main.rs Normal file
View File

@@ -0,0 +1,69 @@
use std::env;
use std::fmt::Display;
use std::process::ExitCode;
use lib::submit_with_name;
fn main() -> ExitCode {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: main NAME");
return ExitCode::FAILURE;
}
let mut name = args[1].clone();
loop {
println!("\nAttempting to solve for \"{}\"", &name);
print!("Solving challenge 01_welcome... ");
let (n, x) = lib::challenges::c1_welcome::solve();
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 02_these_numbers_are_big... ");
let (n, x) = lib::challenges::c2_these_numbers_are_big::solve(&name);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 03_are_you_still_doing_this_by_hand... ");
let (n, x) = lib::challenges::c3_are_you_still_doing_this_by_hand::solve(n, x);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 04_broken_proof_of_work... ");
let (n, x) = lib::challenges::c4_broken_proof_of_work::solve(n, x);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 05_what_the_bf... ");
let (n, x) = lib::challenges::c5_what_the_bf::solve(n, x);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 06_automation_is_not_enough... ");
let (n, x) = lib::challenges::c6_automation_is_not_enough::solve(n, x);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 07_weird_assembly_machine... ");
let (n, x) = lib::challenges::c7_weird_assembly_machine::solve(n, x);
submit_or_fail(&name, n, x.clone());
print!("Solving challenge 08_revisit_everything... ");
let (n, x) = match lib::challenges::c8_revisit_everything::solve(n, x) {
Ok(res) => res,
Err(w) => {
println!("Failed. (w = {})", w);
name.insert_str(0, " ");
continue;
}
};
submit_or_fail(&name, n, x.clone());
println!("n = {}", n);
println!("x = {}", x);
break;
}
ExitCode::SUCCESS
}
fn submit_or_fail<T1: Display + Send, T2: Display + Send>(name: &str, n: T1, x: T2) {
match submit_with_name(name, n, x) {
Ok(_) => println!("Success."),
Err(err) => println!("Failure: {}", err),
}
}

View File

@@ -0,0 +1,3 @@
pub fn solve() -> (u64, u64) {
(10000, 4)
}

View File

@@ -0,0 +1,25 @@
use std::str::FromStr;
use lazy_static::lazy_static;
use rug::Integer;
use rug::integer::Order;
use sha2::{Sha256, Digest};
lazy_static!(
static ref M: Integer = Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap();
static ref E: Integer = Integer::from(65537);
);
pub fn solve(name: &str) -> (u64, Integer) {
let mut x = sha256(name);
x += 4;
for _ in 0..10_000 {
for _ in 0..100 {
x.pow_mod_mut(&E, &M).unwrap();
}
}
(20_000, x)
}
pub fn sha256(name: &str) -> Integer {
Integer::from_digits(Sha256::digest(name).as_slice(), Order::MsfBe)
}

View File

@@ -0,0 +1,151 @@
use lazy_static::lazy_static;
use rug::Integer;
use std::collections::HashMap;
use std::io::{stdout, Write};
use tqdm::tqdm;
const P: u64 = 12345679943u64;
lazy_static!(
static ref BABY_STEPS: Vec<u64> = std::fs::read("res/03_baby_steps.bin").unwrap()
.chunks_exact(8)
.map(|chunk| u64::from_be_bytes(chunk.try_into().unwrap()))
.collect();
static ref GIANT_STEPS: HashMap<u64, usize> = std::fs::read("res/03_giant_steps.bin").unwrap()
.chunks_exact(8)
.map(|chunk| u64::from_be_bytes(chunk.try_into().unwrap()))
.enumerate()
.map(|(idx, step)| (step, idx))
.collect();
);
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
let x = x.modulo(&Integer::from(P - 1)).to_u64().unwrap();
let mut n = n;
let mut x = x.clone();
for _ in 0..10_000 {
n += 1;
x = log42_mod_p(1 + (x + n) % (P - 1)).unwrap();
}
(n, Integer::from(x))
}
fn log42_mod_p(b: u64) -> Option<u64> {
if b % P == 1 {
return Some(0);
}
let inv = pow(b, P - 2, P) as u128;
let s = GIANT_STEPS.len();
for j in 1..=BABY_STEPS.len() {
let baby_step = BABY_STEPS[j - 1] as u128;
let search = ((baby_step * inv) % P as u128) as u64;
if let Some(i) = GIANT_STEPS.get(&search) {
return Some((j * s - i) as u64);
}
}
None
}
pub fn precompute() {
let g = 42u64;
let m = P;
let s = 5341666;
precompute_giant_steps(g, m, s);
precompute_baby_steps(g, m, s);
}
fn precompute_giant_steps(g: u64, m: u64, s: u64) {
let g = g as u128;
let m = m as u128;
let mut a = 1u128;
for _ in tqdm(0..s) {
stdout().write_all(&(a as u64).to_be_bytes()).unwrap();
a *= g;
a %= m;
}
}
fn precompute_baby_steps(g: u64, m: u64, s: u64) {
let gs = pow(g, s, m) as u128;
let m= m as u128;
let mut a = gs;
for _ in tqdm(1..=(m as u64 / s + 1)) {
stdout().write_all(&(a as u64).to_be_bytes()).unwrap();
a *= gs;
a %= m;
}
}
fn log(g: u64, b: u64, m: u64) -> Option<u64> {
let g: u128 = g as u128;
let b: u128 = b as u128;
let m: u128 = m as u128;
let s = m.isqrt() + 1;
let mut r = HashMap::new();
let mut a = b % m;
if a == 1 {
return Some(0);
}
for i in 0..s {
r.insert(a, i);
a *= g;
a %= m;
}
let gs = pow(g as u64, s as u64, m as u64) as u128;
a = gs;
for j in 1..=s {
if let Some(i) = r.get(&a) {
return Some((j * s - i) as u64);
}
a *= gs;
a %= m;
}
None
}
fn pow(a: u64, mut k: u64, m: u64) -> u64 {
let mut a: u128 = a as u128;
let m: u128 = m as u128;
let mut b = 1u128;
while k != 0 {
if k % 2 == 1 {
b *= a;
b %= m;
}
a *= a;
a %= m;
k >>= 1;
}
b as u64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn log_test() {
assert_eq!(log(3, 12, 23), Some(4));
assert_eq!(log(2, 3, 5), Some(3));
log(42, 3816393254, 12345679943);
}
#[test]
fn pow_test() {
assert_eq!(pow(2, 3, 5), 3);
assert_eq!(pow(3, 4, 23), 12);
}
}

View File

@@ -0,0 +1,17 @@
use rug::Integer;
const LIMIT: u64 = 100_000_000;
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
let k = LIMIT - n;
let mut x = x + (k / 4) * 1_640_000;
for _ in 0..k%4 {
for _ in 0..10000 {
x += 41;
x ^= 42;
}
}
(LIMIT, x)
}

View File

@@ -0,0 +1,33 @@
use rug::{Assign, Integer};
const LIMIT: u64 = 1_000_000_000_000u64;
const M: u64 = 1_000_000_000_000u64 - 11;
// x_{n+1} = 1/11 * x mod (10^12 - 11)
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
let k = LIMIT - n - 1;
let mut x = x;
for _ in 0..100 {
let y = x.to_u128().unwrap();
x.assign(f(y));
}
let a = Integer::from(11).pow_mod(&Integer::from(-1), &Integer::from(M)).unwrap();
let b = a.pow_mod(&Integer::from(100 * k), &Integer::from(M)).unwrap();
(LIMIT, x * b % &M)
}
const A: u128 = 909_090_909_091u128; // (10 * b + 1) / 11
const B: u128 = 1_000_000_000_000u128; // 10^12
const C: u128 = 999_999_999_989u128; // b - 11
const D: u128 = 999_999_999_999u128; // b - 1
fn f(mut x: u128) -> u128 {
x = x * A % B;
x = (x * C + D) / B;
x
}

View File

@@ -0,0 +1,26 @@
use lazy_static::lazy_static;
use rug::Integer;
use std::str::FromStr;
const START: u64 = 1_000_000_000_000u64;
const LIMIT: u64 = 10_000_000_000_000_000u64;
lazy_static!(
static ref M: Integer = Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap();
static ref A: Integer = Integer::from_str("10729297455904899337681752672816753703351288544833760635567859176397566160330812285369370751389224534974913042757043771146367160829669925123791471756026119030734890865062863499420767799283504416995775836275660636668989077836006690621539265605").unwrap();
static ref B: Integer = Integer::from_str("4997609466256208183077203585670710326160976219126614124062259398288517298185253986607627790890962248558793881836308854443463332741665631247256917127102588793451033551034614994254514161235462726178612824897626185944163885786520174491419225456").unwrap();
);
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
assert_eq!(n, START);
let m: &Integer = &M;
let a: &Integer = &A;
let b: &Integer = &B;
let mut x = x;
x = (x + a) % m;
x = x * 2 % m;
x = (x + b) % m;
(LIMIT, x)
}

View File

@@ -0,0 +1,128 @@
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::str::FromStr;
use lazy_static::lazy_static;
use rug::Integer;
lazy_static!(
static ref DATA: Vec<u64> = {
let file = File::open("./res/07_weird_assembly_machine.data");
let lines = BufReader::new(file.unwrap()).lines();
let mut data = Vec::new();
for line in lines {
data.push(u64::from_str(&line.unwrap()).unwrap());
}
data
};
);
const LIMIT: u64 = 1_000_000_000_000_000_000u64;
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
let x = x.to_u64_wrapping();
let (n, x) = f_n(n, x, LIMIT - n);
(n, Integer::from(x))
}
pub fn f_n(mut n: u64, mut x: u64, k: u64) -> (u64, u64) {
n += 1;
x = sub(f(x), n);
let fast_k = (k - 1) / 192 * 192;
let sum = fast_fg_sum(n , fast_k);
x = sub(fg_n(x, fast_k), sum);
n += fast_k;
let remaining = (k - 1) - fast_k;
let sum = fg_sum(n, remaining);
x = sub(fg_n(x, remaining), sum);
n += remaining;
x = g(x);
(n, x)
}
fn fg_sum(n: u64, k: u64) -> u64 {
let mut sum = 0u64;
for i in 1..=k {
sum = add(sum, fg_n(n + i, k - i));
}
sum
}
fn fast_fg_sum(n: u64, k: u64) -> u64 {
debug_assert!(k % 192 == 0);
let mut result = fg_sum(n, 0);
result = add(result, ((13556435138434861179u128 * (k / 192) as u128) % (u64::MAX as u128)) as u64);
result
}
fn f(x: u64) -> u64 {
evaluate(x, &DATA[..128], &DATA[..128])
}
fn g(x: u64) -> u64 {
evaluate(x, &DATA[128..], &DATA[128..])
}
fn add(a: u64, b: u64) -> u64 {
let (result, overflow) = a.overflowing_add(b);
result + overflow as u64
}
fn sub(x: u64, mut n: u64) -> u64 {
if x <= n {
n += 1;
}
x.wrapping_sub(n)
}
fn fg(x: u64) -> u64 {
!x.rotate_left(17)
}
fn fg_n(mut x: u64, n: u64) -> u64 {
for _ in 0..n%64 {
x = fg(x);
}
x
}
fn evaluate(x: u64, data_even: &[u64], data_odd: &[u64]) -> u64 {
let data = if x.count_ones() % 2 == 0 { data_even } else { data_odd };
let mut out = 0;
for i in 0..data.len() {
out = xor_mul(out, x) ^ data[i];
}
out
}
#[cfg(not(all(target_arch = "x86_64", target_feature = "pclmulqdq")))]
fn xor_mul(a: u64, mut b: u64) -> u64 {
let mut x: u64 = 0;
while b != 0 {
let c = b.trailing_zeros();
b = b ^ 1u64.rotate_left(c);
x = x ^ a.rotate_left(c);
}
x
}
#[cfg(all(target_arch = "x86_64", target_feature = "pclmulqdq"))]
fn xor_mul(a: u64, b: u64) -> u64 {
use std::arch::x86_64::*;
unsafe {
let a_vec = _mm_set_epi64x(0, a as i64);
let b_vec = _mm_set_epi64x(0, b as i64);
let result = _mm_clmulepi64_si128(a_vec, b_vec, 0x00);
// Extract both 64-bit halves and XOR them
let low = _mm_extract_epi64(result, 0) as u64;
let high = _mm_extract_epi64(result, 1) as u64;
low ^ high
}
}

View File

@@ -0,0 +1,27 @@
use rug::ops::DivRounding;
use rug::Integer;
use std::str::FromStr;
const PHI: &str = "4556683258594822402855414380362620295231673046713752880933967889771646856051745784462468117575177892006513392693685616565666555545842363207724851343853529903674824524238732001458342230627654145983386115997227846421784693186847971068054052064";
const M: &str = "4556683258594822402855414380362620295231673046713752880933967889771646856051745784462468117575177892006513392693685616569935833357648393898915677206732580748330214938398411668157941515847730087263301030154072458063812554524260405671629754999";
const E: u64 = 65537;
const LIMIT: u128 = 100_000_000_000_000_000_000;
pub fn solve(n: u64, x: Integer) -> Result<(u128, Integer), u32> {
let truth = Integer::from(42);
let phi = Integer::from_str(PHI).unwrap();
let m = Integer::from_str(M).unwrap();
let k = Integer::from(LIMIT - n as u128) * 100;
let e = Integer::from(E).pow_mod(&k, &phi).unwrap();
let w: u32 = x.clone().modulo(&truth).try_into().unwrap();
if w != 30 {
return Err(w);
}
let mut y = x.clone().div_floor(&truth);
y = y.pow_mod(&e, &m).unwrap();
let x: Integer = y * 42 + w;
Ok((LIMIT, x))
}

View File

@@ -0,0 +1,8 @@
pub mod c1_welcome;
pub mod c2_these_numbers_are_big;
pub mod c3_are_you_still_doing_this_by_hand;
pub mod c4_broken_proof_of_work;
pub mod c5_what_the_bf;
pub mod c6_automation_is_not_enough;
pub mod c7_weird_assembly_machine;
pub mod c8_revisit_everything;

View File

@@ -1,4 +1,5 @@
use anyhow::{Result, anyhow}; #![allow(dead_code)]
use anyhow::{anyhow, Result};
use json::JsonValue; use json::JsonValue;
use std::fmt::Display; use std::fmt::Display;
use std::sync::mpsc; use std::sync::mpsc;
@@ -7,20 +8,42 @@ use std::thread;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::time::Instant; use std::time::Instant;
pub mod challenges;
const USER_NAME: &str = "Jonah"; const USER_NAME: &str = "Jonah";
pub fn compute_async<T: Display + Send + 'static, R: Send + 'static>(mut function: impl FnMut(Sender<(T, T)>) -> R + Send + 'static ) -> R { pub fn compute_async<
let (tx, jh1) = spawn_submission_thread(); T1: Display + Send + 'static,
let jh2 = thread::spawn(move || { T2: Display + Send + 'static,
function(tx) R: Send + 'static
}); >(
function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static
jh1.join().unwrap(); ) -> R {
jh2.join().unwrap() compute_async_with_name(USER_NAME, function)
} }
pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>, JoinHandle<()>) {
let (tx, rx) = mpsc::channel::<(T, T)>(); pub fn compute_async_with_name<
T1: Display + Send + 'static,
T2: Display + Send + 'static,
R: Send + 'static
>(
name: &'static str,
mut function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static
) -> R {
let (tx, jh) = spawn_submission_thread(name);
let result = function(tx);
jh.join().unwrap();
result
}
pub fn spawn_submission_thread<
T1: Display + Send + 'static,
T2: Display + Send + 'static
>(
name: &'static str
) -> (Sender<(T1, T2)>, JoinHandle<()>) {
let (tx, rx) = mpsc::channel::<(T1, T2)>();
let handle = thread::spawn(move || { let handle = thread::spawn(move || {
let mut t = Instant::now(); let mut t = Instant::now();
for (n, x) in rx { for (n, x) in rx {
@@ -28,7 +51,7 @@ pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>
println!("\nn = {n}\nx = {x}\nduration = {}", t2.duration_since(t).as_millis()); println!("\nn = {n}\nx = {x}\nduration = {}", t2.duration_since(t).as_millis());
t = t2; t = t2;
match submit(n, x) { match submit_with_name(name, n, x) {
Ok(_) => {} Ok(_) => {}
Err(err) => eprintln!("{:?}", err), Err(err) => eprintln!("{:?}", err),
}; };
@@ -37,8 +60,23 @@ pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>
(tx, handle) (tx, handle)
} }
pub fn submit<T: Display + Send>(n: T, x: T) -> Result<Option<String>> { pub fn submit<
let url = format!("https://button.qedaka.de/server.php?name={USER_NAME}&n={n}&x={x}"); T1: Display + Send,
T2: Display + Send
>(
n: T1, x: T2
) -> Result<Option<String>> {
submit_with_name(USER_NAME, n, x)
}
pub fn submit_with_name<
T1: Display + Send,
T2: Display + Send
>(
name: &str, n: T1, x: T2
) -> Result<Option<String>> {
let name = percent_encoding::percent_encode(name.as_bytes(), percent_encoding::NON_ALPHANUMERIC);
let url = format!("https://button.qedaka.de/server.php?name={}&n={n}&x={x}", name);
let body = reqwest::blocking::get(url)?.text()?; let body = reqwest::blocking::get(url)?.text()?;
match json::parse(&body)? { match json::parse(&body)? {
JsonValue::Object(obj) => { JsonValue::Object(obj) => {