diff --git a/Cargo.toml b/Cargo.toml index 2dda746..fce6320 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ json = "0.12.4" reqwest = { version = "0.12.23", features = ["blocking"] } rug = { version = "1.28.0", features = ["integer"], default-features = false } tqdm = "0.8.0" +sha2 = "0.10.9" +percent-encoding = "2.3.2" [lib] name = "lib" diff --git a/src/bin/07_weird_assembly_machine.rs b/src/bin/07_weird_assembly_machine.rs index 7b0c3ea..05c0809 100644 --- a/src/bin/07_weird_assembly_machine.rs +++ b/src/bin/07_weird_assembly_machine.rs @@ -1,1221 +1,12 @@ -#![allow(dead_code)] - -use std::fs::File; -use std::io::{BufRead, BufReader}; -use std::str::FromStr; -use std::sync::LazyLock; use lib::submit; +use lib::challenges::c7_weird_assembly_machine::h_n; -static DATA: LazyLock> = LazyLock::new(|| { - 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 N: u64 = 10000117800000000; -const X: u64 = 5905739161907566595; +const N: u64 = 979607657800000055; +const X: u64 = 10962444957429324784; fn main() { let (n, x) = h_n(N, X, 1_000_000_000_000_000_000u64 - N); + println!("n = {n}"); + println!("x = {x}"); submit(n, x).unwrap(); -} - -fn h(x: u64, n: u64) -> u64 { - g(sub(f(x), n)) -} - -fn h_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 f(x: u64) -> u64 { - evaluate(x, &DATA[0..128]) -} - -fn g(x: u64) -> u64 { - evaluate(x, &DATA[128..256]) -} - -/// Quickly computes [`f`](f)([`g`](g)(x)). -fn fg(x: u64) -> u64 { - !x.rotate_left(17) -} - -/// Computes [`fg`](fg)(...[`fg`](fg)(x)...) where [`fg`] is applied `n` times. -fn fg_n(mut x: u64, n: u64) -> u64 { - for _ in 0..n%64 { - x = fg(x); - } - x -} - -/// Computes the sum from `i = 1` to `k` over `fg^(k-i)(n + i)`. -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 -} - -/// Quickly computes `fg_sum` when `k` is divisible by `192`. -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 -} - -/// Evaluates a polynomial over `GF(2)[X] / (X^64 + 1)` -fn evaluate(x: u64, data: &[u64]) -> u64 { - let mut out = 0; - for i in 0..data.len() { - out = xor_mul(out, x) ^ data[i]; - } - out -} - -fn add(a: u64, b: u64) -> u64 { - let (result, overflow) = a.overflowing_add(b); - result + overflow as u64 -} - -fn sub(a: u64, mut b: u64) -> u64 { - if a <= b { - b += 1; - } - a.wrapping_sub(b) -} - -#[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 - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn func0test() { - assert_eq!(2275218980137066521, xor_mul(823376445, 2933488917)); - assert_eq!(7026402047137357602, xor_mul(3691543355, 2547548462)); - assert_eq!(1360720565456786886, xor_mul(1631669653, 1943537758)); - assert_eq!(6206853381339280580, xor_mul(3418720847, 3281877132)); - assert_eq!(3821249963754522024, xor_mul(1289221960, 3243927869)); - assert_eq!(882431475059032604, xor_mul(367193564, 4097712529)); - assert_eq!(4926161117160240706, xor_mul(3436171671, 4292693206)); - assert_eq!(3115965114924228534, xor_mul(1753842422, 3687497057)); - assert_eq!(8734691127450451974, xor_mul(4044078733, 2197737550)); - assert_eq!(2943203761612760392, xor_mul(1244650136, 2964402935)); - assert_eq!(6772758496796810062, xor_mul(3178786959, 2277874162)); - assert_eq!(164002738127771409, xor_mul(2431906895, 67872835)); - assert_eq!(2534635611824557864, xor_mul(1526866754, 2980150036)); - assert_eq!(2281422676663357779, xor_mul(1974321509, 1338155343)); - assert_eq!(4809582189839732169, xor_mul(2231376997, 2155687005)); - assert_eq!(7997326223635490910, xor_mul(3333279658, 2464875795)); - assert_eq!(564698454155766592, xor_mul(3819982240, 158798722)); - assert_eq!(150358408295203874, xor_mul(1407059918, 178123531)); - assert_eq!(2950877544101808616, xor_mul(4027467880, 2130465393)); - assert_eq!(7433963866346235715, xor_mul(3231972439, 2337659549)); - assert_eq!(97718272192598598, xor_mul(135080626, 727604235)); - assert_eq!(2019072571720999028, xor_mul(2117949580, 1226677547)); - assert_eq!(4064354319484950360, xor_mul(1685177180, 3015516490)); - assert_eq!(829978590409745198, xor_mul(1043018378, 1910838971)); - assert_eq!(1343743912543815608, xor_mul(1931247249, 1611122744)); - assert_eq!(344344082533737885, xor_mul(1622600431, 499885623)); - assert_eq!(2258376149702545739, xor_mul(1116642871, 2119709157)); - assert_eq!(870036298768927356, xor_mul(510143124, 2841548211)); - assert_eq!(2291729428506812433, xor_mul(822131093, 2919079061)); - assert_eq!(1942041239928076416, xor_mul(2427487936, 866869806)); - assert_eq!(4413542076532948168, xor_mul(1142011985, 4204104264)); - assert_eq!(7725503794949940832, xor_mul(2652944930, 3355197488)); - assert_eq!(572731058715430966, xor_mul(346457467, 1706449986)); - assert_eq!(771384575430546132, xor_mul(349225434, 2383068914)); - assert_eq!(6720471466404264298, xor_mul(2734432761, 2683021530)); - assert_eq!(10114228482972006, xor_mul(6443214, 4037181469)); - assert_eq!(1462086330404018156, xor_mul(2261477748, 692328079)); - assert_eq!(4248125061804235846, xor_mul(1462734411, 3599520562)); - assert_eq!(438254739184660816, xor_mul(150017636, 3401841844)); - assert_eq!(924924009899234107, xor_mul(1890984405, 796124759)); - assert_eq!(1583433247430081905, xor_mul(1511929045, 1335064885)); - assert_eq!(344452189567184841, xor_mul(287207665, 1216709049)); - assert_eq!(8408046965142065312, xor_mul(4005765152, 2223455621)); - assert_eq!(2340737587100291955, xor_mul(2250772451, 1140023921)); - assert_eq!(1011391340612719836, xor_mul(1260502354, 1055586398)); - assert_eq!(4539082446856232019, xor_mul(1275385147, 3900684569)); - assert_eq!(2073697442264457591, xor_mul(807071233, 3145796471)); - assert_eq!(464008672190170508, xor_mul(2328300556, 203128353)); - assert_eq!(1750720338177427574, xor_mul(2052773661, 1464133406)); - assert_eq!(2818450916558278418, xor_mul(1307950731, 2266653278)); - assert_eq!(3087550251367439382, xor_mul(3748440942, 1748394149)); - assert_eq!(31065924273406873, xor_mul(28131655, 1185107827)); - assert_eq!(1637091247100653372, xor_mul(2583625587, 719595348)); - assert_eq!(1187803888684817137, xor_mul(955126175, 3662511859)); - assert_eq!(1076693608643937976, xor_mul(2415810454, 479440468)); - assert_eq!(886932995053456855, xor_mul(1998857853, 785872531)); - assert_eq!(4041577507147387694, xor_mul(1989558127, 2317016338)); - assert_eq!(3195373375008716592, xor_mul(1544958382, 2317403752)); - assert_eq!(4344034197574385581, xor_mul(1163146903, 4257380511)); - assert_eq!(4548739690401687331, xor_mul(1816152237, 3218195687)); - assert_eq!(5688846906041887124, xor_mul(4241496484, 3500572141)); - assert_eq!(3748650067680712929, xor_mul(1670205605, 2600188565)); - assert_eq!(4489150664351988267, xor_mul(3047056993, 1752871819)); - assert_eq!(3552290940876679256, xor_mul(2242739114, 1630483100)); - assert_eq!(8404550793217443760, xor_mul(2273636432, 3969930983)); - assert_eq!(1348409384823762177, xor_mul(1007538615, 3531004331)); - assert_eq!(3545691341191605002, xor_mul(1926409210, 3055258457)); - assert_eq!(1627039133669989128, xor_mul(1103530570, 1540713044)); - assert_eq!(337319684340642581, xor_mul(1071722095, 936379311)); - assert_eq!(2488111028592156108, xor_mul(1363867182, 2686974746)); - assert_eq!(1838074366800239376, xor_mul(1986957250, 1524007560)); - assert_eq!(375258788906303722, xor_mul(3294750862, 201986535)); - assert_eq!(6087525133192784177, xor_mul(3763006281, 3772000697)); - assert_eq!(1250706533780855424, xor_mul(2592292625, 618017408)); - assert_eq!(1567055362944800611, xor_mul(821519937, 3400471971)); - assert_eq!(3839668165238544140, xor_mul(4126323486, 1498898218)); - assert_eq!(5154501295052475800, xor_mul(3753548118, 4004509476)); - assert_eq!(276252029851915445, xor_mul(2169263253, 128333985)); - assert_eq!(4303845948374636936, xor_mul(1219406786, 4048413508)); - assert_eq!(8955630451326320612, xor_mul(2308854182, 4142939790)); - assert_eq!(3950342623314748312, xor_mul(2635951912, 1687868271)); - assert_eq!(1347719876603310184, xor_mul(978203467, 3440087448)); - assert_eq!(4325169701035756612, xor_mul(2021926123, 2172822044)); - assert_eq!(1123560531444408352, xor_mul(2415743450, 510384080)); - assert_eq!(302367434318115088, xor_mul(1695451564, 510042140)); - assert_eq!(5425253682140093808, xor_mul(2454871170, 2220814520)); - assert_eq!(1440678434476164920, xor_mul(941214316, 3378223338)); - assert_eq!(6738906437434918068, xor_mul(3161261478, 2254805142)); - assert_eq!(1200367617776126876, xor_mul(4107039252, 866921035)); - assert_eq!(4356587871866293326, xor_mul(1202192174, 4225386321)); - assert_eq!(918255447474733459, xor_mul(1296132779, 932888873)); - assert_eq!(286069664049683456, xor_mul(1223290368, 238264130)); - assert_eq!(737264942432347260, xor_mul(3336065407, 411345540)); - assert_eq!(360102161648468383, xor_mul(332266485, 1087376259)); - assert_eq!(531469479175514084, xor_mul(837869778, 752496162)); - assert_eq!(5488021351449658331, xor_mul(4053318219, 3627637233)); - assert_eq!(2195117409397730144, xor_mul(1281698344, 1888304668)); - assert_eq!(763462177913700116, xor_mul(323851131, 3063765996)); - assert_eq!(4040244555080779916, xor_mul(1658170916, 3092066683)); - assert_eq!(3852821034638912936, xor_mul(1753274702, 2278544668)); - assert_eq!(4041373326734813864, xor_mul(2263341818, 1915177764)); - assert_eq!(1963702993615069667, xor_mul(1919728625, 1382000883)); - assert_eq!(4877789904824206100, xor_mul(3361201225, 4026614708)); - assert_eq!(30179695802284800, xor_mul(63431512, 768970272)); - assert_eq!(1449592659987634229, xor_mul(1612461201, 1615233253)); - assert_eq!(4261547527047212185, xor_mul(1965217825, 2238776249)); - assert_eq!(8423406086031164118, xor_mul(4281074866, 2643256195)); - assert_eq!(1782123918688200992, xor_mul(1418043636, 2071419944)); - assert_eq!(1047489370443739329, xor_mul(2764618499, 454805695)); - assert_eq!(2934673406450453408, xor_mul(4134873516, 2100643096)); - assert_eq!(5650705393643171844, xor_mul(2943771772, 3197035875)); - assert_eq!(1038767850510879704, xor_mul(1267164458, 1060555612)); - assert_eq!(4204937883267119488, xor_mul(1646378432, 3071105114)); - assert_eq!(411829728143907900, xor_mul(4104299556, 243262903)); - assert_eq!(7871739648472512000, xor_mul(3892839244, 2908343424)); - assert_eq!(2984675312994870904, xor_mul(3160475925, 1312301464)); - assert_eq!(21035103484703632, xor_mul(162635036, 150285900)); - assert_eq!(3251194670058000317, xor_mul(2379882081, 1573406045)); - assert_eq!(110250149841963592, xor_mul(534172326, 343271772)); - assert_eq!(7078970850659721868, xor_mul(2244340883, 3275910212)); - assert_eq!(2725272366739724240, xor_mul(1949499772, 3488175260)); - assert_eq!(595614546781317578, xor_mul(532656446, 3304604751)); - assert_eq!(4117176559172186460, xor_mul(2144016228, 2527036959)); - assert_eq!(2632599442184004850, xor_mul(1195711793, 2649908626)); - assert_eq!(8283259829447755662, xor_mul(4242278674, 2515258815)); - assert_eq!(8576464463094299940, xor_mul(3718522222, 2812874342)); - assert_eq!(1921698232043823400, xor_mul(1109599650, 1775528660)); - assert_eq!(1154402324203904172, xor_mul(1476051740, 1384187285)); - assert_eq!(455463673979035594, xor_mul(214276239, 2219875006)); - assert_eq!(2384533312140370925, xor_mul(3175026621, 1491797393)); - assert_eq!(1891967452146534940, xor_mul(990728773, 2804246444)); - assert_eq!(8051443749879688498, xor_mul(2551326570, 3398973725)); - assert_eq!(610551727018460416, xor_mul(2081384706, 815047296)); - assert_eq!(986636632557619796, xor_mul(902596084, 1155254281)); - assert_eq!(1091429410910539584, xor_mul(478991904, 2657795994)); - assert_eq!(8776624415569207203, xor_mul(2977137159, 3727366797)); - assert_eq!(382219229381305275, xor_mul(646537673, 767549155)); - assert_eq!(3879007306152627155, xor_mul(4284337903, 1578339205)); - assert_eq!(5640927286993029844, xor_mul(3876557086, 3452918622)); - assert_eq!(1998985482433578131, xor_mul(2042549347, 1566472785)); - assert_eq!(2168046308224159248, xor_mul(1457939723, 1686938480)); - assert_eq!(4466965408553605840, xor_mul(2457856272, 1956085501)); - assert_eq!(1067663693542443033, xor_mul(977508429, 1128940005)); - assert_eq!(8860666141481256660, xor_mul(3985583770, 2544156338)); - assert_eq!(745516573917847823, xor_mul(480123883, 4004776317)); - assert_eq!(6438483768859797674, xor_mul(3143262762, 2324635713)); - assert_eq!(3254090421191095208, xor_mul(3620879492, 1728307114)); - assert_eq!(1340483629302253568, xor_mul(3428653120, 980314656)); - assert_eq!(2411345400251493265, xor_mul(2399278795, 1158313383)); - assert_eq!(6651644068546691056, xor_mul(3699784488, 3449780262)); - assert_eq!(6292307452484462516, xor_mul(2235066222, 2861630718)); - assert_eq!(681387698627300975, xor_mul(1650061851, 943566413)); - assert_eq!(8383786330681871058, xor_mul(3338203166, 3051808523)); - assert_eq!(8556366266451367696, xor_mul(3754229852, 2794985068)); - assert_eq!(5879489647181272672, xor_mul(2452073158, 3072584464)); - assert_eq!(3254887619117977121, xor_mul(2252534289, 1507028785)); - assert_eq!(1891777769572061084, xor_mul(3873245929, 716324604)); - assert_eq!(716988359874547192, xor_mul(3201491255, 361375432)); - assert_eq!(8773276214145328288, xor_mul(4115558392, 2244003260)); - assert_eq!(1557858294476708064, xor_mul(2354601828, 686262392)); - assert_eq!(6517694501844039680, xor_mul(3398545856, 3549470752)); - assert_eq!(4066267488082735696, xor_mul(1758402864, 2805295731)); - assert_eq!(3595903941024271292, xor_mul(1413796534, 4117469210)); - assert_eq!(4741134743254315904, xor_mul(2325717790, 2310876736)); - assert_eq!(266074381549681662, xor_mul(1881177169, 146222494)); - assert_eq!(6058711024417491765, xor_mul(2204038291, 2879243651)); - assert_eq!(1718993490673745892, xor_mul(2459229789, 712918100)); - assert_eq!(2716445728417641712, xor_mul(1233340744, 2239562798)); - assert_eq!(8745705085685282468, xor_mul(2695032622, 3270520678)); - assert_eq!(240884880814460464, xor_mul(185694725, 2073299440)); - assert_eq!(370338321743340060, xor_mul(1927878045, 500448908)); - assert_eq!(5573963629959711288, xor_mul(3708488923, 4134848168)); - assert_eq!(541758693581570993, xor_mul(3382379489, 181618257)); - assert_eq!(1815967889786955188, xor_mul(1429495489, 2108672692)); - assert_eq!(4041604264929827155, xor_mul(3249256207, 1600814245)); - assert_eq!(952003732340514366, xor_mul(337370794, 3918218595)); - assert_eq!(4332233817724496798, xor_mul(1812951086, 3063286953)); - assert_eq!(1758658545102429502, xor_mul(2746796405, 1065632262)); - assert_eq!(540269665119950416, xor_mul(1585842566, 433209112)); - assert_eq!(2331775051124288019, xor_mul(2065558545, 3398949923)); - assert_eq!(307490286585000947, xor_mul(461817349, 1948269263)); - assert_eq!(960292366624895421, xor_mul(1543654715, 1053356755)); - assert_eq!(2157515180864683421, xor_mul(3298669099, 751530403)); - assert_eq!(487852033197913091, xor_mul(1927701481, 350032635)); - assert_eq!(2984595772390019960, xor_mul(3545686998, 1800861044)); - assert_eq!(3392204407324397988, xor_mul(2173364313, 1589689028)); - assert_eq!(1687946440198430352, xor_mul(4177494640, 944731779)); - assert_eq!(39287165401589762, xor_mul(1991068770, 57386801)); - assert_eq!(1100437088382813246, xor_mul(1577671925, 878786054)); - assert_eq!(862950049948957457, xor_mul(1662101853, 887867421)); - assert_eq!(2332695340952914938, xor_mul(3280480578, 2122372317)); - assert_eq!(462363662690671169, xor_mul(545694885, 866050229)); - assert_eq!(3052771912967790776, xor_mul(1459213981, 2241587096)); - assert_eq!(920814936415458234, xor_mul(2134665779, 718464502)); - assert_eq!(70831990903737178, xor_mul(853535583, 85914286)); - assert_eq!(1344859749633130679, xor_mul(2157802473, 628177775)); - assert_eq!(3428977288760135037, xor_mul(1791083763, 3251293275)); - assert_eq!(1721466933995983702, xor_mul(3738274869, 847866702)); - assert_eq!(3384471763492985384, xor_mul(3414274072, 1814298819)); - assert_eq!(2192502073650024941, xor_mul(2890196027, 852102243)); - assert_eq!(1733565508298695626, xor_mul(2792063762, 1051404813)); - assert_eq!(1532023292037786912, xor_mul(2370877684, 689901864)); - assert_eq!(559614790651608242, xor_mul(291650478, 2063352163)); - assert_eq!(5619240326630354996, xor_mul(2727081038, 3031714974)); - assert_eq!(6190657267302765724, xor_mul(4192667396, 4161955943)); - assert_eq!(679208445002198844, xor_mul(2116906316, 933317045)); - assert_eq!(1430495629237040970, xor_mul(2195270695, 656040174)); - assert_eq!(1758830525608466631, xor_mul(4006564763, 801380245)); - assert_eq!(4625807642296379568, xor_mul(3476098436, 4085248172)); - assert_eq!(4248813050677024640, xor_mul(1756035124, 2867110752)); - assert_eq!(3429570552635333824, xor_mul(1589085520, 2209700604)); - assert_eq!(4750842979111071920, xor_mul(2336421774, 2284355496)); - assert_eq!(1021348587074499006, xor_mul(608186674, 2119354007)); - assert_eq!(2650438524731897405, xor_mul(3278912387, 1894748779)); - assert_eq!(1351722393614577911, xor_mul(3873437327, 814233097)); - assert_eq!(2686403937481637342, xor_mul(2194661374, 1272337201)); - assert_eq!(164459815905328414, xor_mul(3372082866, 121763335)); - assert_eq!(5470234883889678, xor_mul(376314766, 21646145)); - assert_eq!(2007298046738591390, xor_mul(612987929, 3310593550)); - assert_eq!(7579170471480569320, xor_mul(2919769722, 3772899844)); - assert_eq!(3968476460573009653, xor_mul(1948625227, 2832099163)); - assert_eq!(4340678797444951998, xor_mul(3191445514, 1807390099)); - assert_eq!(7832464371503197486, xor_mul(2994368086, 4218339445)); - assert_eq!(982620286037513066, xor_mul(619247894, 1613434459)); - assert_eq!(1809487919217160166, xor_mul(2934499234, 1059642243)); - assert_eq!(2227413677592354988, xor_mul(905868166, 3140412082)); - assert_eq!(1958340477793776136, xor_mul(1004501418, 2866117396)); - assert_eq!(590440659472964824, xor_mul(420902903, 4146813608)); - assert_eq!(3970885299515062746, xor_mul(3846845727, 1344431534)); - assert_eq!(164475886718180190, xor_mul(1020415601, 447873278)); - assert_eq!(1062027837126423760, xor_mul(3032151014, 412430936)); - assert_eq!(429619033882122664, xor_mul(1621666264, 448531563)); - assert_eq!(5465767171073422050, xor_mul(3345982579, 3812216638)); - assert_eq!(347658486012260024, xor_mul(1478516335, 350366280)); - assert_eq!(6440862574948199618, xor_mul(3782557837, 4098062842)); - assert_eq!(1270604464903699470, xor_mul(1751112038, 1890371245)); - assert_eq!(3990241783457318167, xor_mul(2091942305, 3077482359)); - assert_eq!(3095411610704251470, xor_mul(3928441734, 1952104285)); - assert_eq!(1069952684789806615, xor_mul(3188097795, 432905997)); - assert_eq!(1549510620786047412, xor_mul(3674778462, 878268622)); - assert_eq!(1429727667635371368, xor_mul(599105724, 2443677518)); - assert_eq!(889132028527773456, xor_mul(3417495052, 292769468)); - assert_eq!(1109664055108497692, xor_mul(1000278385, 1272878172)); - assert_eq!(2990842971177857614, xor_mul(1226065605, 2998674070)); - assert_eq!(4894085341085904512, xor_mul(2249201185, 2177891968)); - assert_eq!(1859036770300358570, xor_mul(4014348786, 756516621)); - assert_eq!(2451518505915255646, xor_mul(1232096701, 2578825494)); - assert_eq!(2205946059708622052, xor_mul(1641031343, 1385566060)); - assert_eq!(3607888246633189888, xor_mul(1166920549, 3333224960)); - assert_eq!(3409366258867729020, xor_mul(1443805428, 2514027643)); - assert_eq!(4122535696483767818, xor_mul(3152364589, 1628836498)); - assert_eq!(6584536497103126554, xor_mul(3137221462, 2391924179)); - assert_eq!(3245159287932023751, xor_mul(3847638123, 2061142533)); - assert_eq!(4609438965157669332, xor_mul(1542442263, 3568168668)); - assert_eq!(1564728155339319015, xor_mul(630777123, 3179001917)); - assert_eq!(5978365295179605808, xor_mul(2304428272, 2920878405)); - assert_eq!(972742158466457616, xor_mul(2128754666, 803902760)); - assert_eq!(7625899292046064160, xor_mul(3175610740, 4224628456)); - assert_eq!(2983624539619229192, xor_mul(1937022356, 3968084458)); - assert_eq!(5497434190094288088, xor_mul(3313445210, 3951395836)); - assert_eq!(199197631139916560, xor_mul(4086182872, 120131182)); - assert_eq!(2273250670276286060, xor_mul(1194807547, 2073909380)); - assert_eq!(3494453182023216983, xor_mul(2980208217, 1921386399)); - assert_eq!(180270644748392130, xor_mul(1880151370, 249058581)); - assert_eq!(1020687423684566464, xor_mul(3162858504, 403593144)); - assert_eq!(291374995101965483, xor_mul(1173506421, 289551719)); - assert_eq!(6167212839858030320, xor_mul(2237591192, 2940713642)); - assert_eq!(4488824941658136448, xor_mul(2081720640, 2173211942)); - assert_eq!(2206242177574492224, xor_mul(1713226528, 1456526962)); - assert_eq!(8500616454723219552, xor_mul(2185519189, 3894612448)); - assert_eq!(236078952304886049, xor_mul(378394021, 1030145365)); - assert_eq!(3791741142945851634, xor_mul(3533006866, 1079459825)); - assert_eq!(7674861032202750752, xor_mul(3854222824, 2901179220)); - assert_eq!(88593838880189540, xor_mul(479139274, 434522266)); - assert_eq!(3731498617958392025, xor_mul(1735328383, 2168827627)); - assert_eq!(4957327058688802720, xor_mul(3654712552, 3979332484)); - assert_eq!(7586489473623616224, xor_mul(2154882788, 3537252856)); - assert_eq!(5143234237995849488, xor_mul(3236767920, 4099088967)); - assert_eq!(60814690151151476, xor_mul(498610518, 176543174)); - assert_eq!(2494338124570153837, xor_mul(1448467319, 2933168959)); - assert_eq!(733832228618837770, xor_mul(349844931, 2236268166)); - assert_eq!(7844804996009623654, xor_mul(2464193762, 3261818019)); - assert_eq!(5518707381922347405, xor_mul(3166848573, 2843734769)); - assert_eq!(3829929761992272984, xor_mul(2414509228, 1861674690)); - assert_eq!(4094706142515960729, xor_mul(2986286595, 1687969655)); - assert_eq!(345618432118279752, xor_mul(2992767531, 175111800)); - assert_eq!(798568757356499947, xor_mul(560702467, 1518587225)); - assert_eq!(352626257298633474, xor_mul(968320474, 856724989)); - assert_eq!(3570273852672598722, xor_mul(2820928119, 2049887638)); - assert_eq!(3735523136603139435, xor_mul(2522699243, 1753191297)); - assert_eq!(2181915330402303264, xor_mul(3484973196, 717809720)); - assert_eq!(5723993708054967808, xor_mul(2513790800, 2315259616)); - assert_eq!(1727680221548818127, xor_mul(1566988465, 1115445087)); - assert_eq!(5273304784419026355, xor_mul(2456730373, 2151011983)); - assert_eq!(3175623972632029919, xor_mul(1830002671, 3306360913)); - assert_eq!(4447007966674445116, xor_mul(1371836457, 3321051740)); - assert_eq!(3899839142503181672, xor_mul(3608266446, 1171579836)); - assert_eq!(1993558991869011729, xor_mul(2567198675, 845022879)); - assert_eq!(5933240954264181656, xor_mul(2457851548, 2952909370)); - assert_eq!(4597526342616153493, xor_mul(2919650215, 1673911591)); - assert_eq!(1547485473755000787, xor_mul(1760812609, 1863559443)); - assert_eq!(5683553362672329498, xor_mul(3872366101, 3449241586)); - assert_eq!(494769461427248570, xor_mul(4031818898, 199052341)); - assert_eq!(3797776063332282449, xor_mul(1433727141, 3859327461)); - assert_eq!(6588752316325819690, xor_mul(3869514115, 4125126630)); - assert_eq!(391832171403485124, xor_mul(857584047, 838712332)); - assert_eq!(880029967602815000, xor_mul(426878809, 2412794200)); - assert_eq!(7593890349902382474, xor_mul(2745495614, 3940158127)); - assert_eq!(6926956260679816736, xor_mul(3899644216, 3109462188)); - assert_eq!(1731149291020412220, xor_mul(876866220, 2632937341)); - assert_eq!(5660738063111627788, xor_mul(3596395324, 4225200661)); - assert_eq!(1788936071689986148, xor_mul(3206921692, 984843907)); - assert_eq!(874573593734676768, xor_mul(2550097481, 463767584)); - assert_eq!(1182143537867310080, xor_mul(1700803120, 2062119872)); - assert_eq!(8393752603899524206, xor_mul(4260442877, 2681042150)); - assert_eq!(1782297911710605872, xor_mul(672832912, 4215320203)); - assert_eq!(7052660320218896402, xor_mul(4169531158, 2817369775)); - assert_eq!(5966122521260465752, xor_mul(3293987770, 3266008572)); - assert_eq!(493613352831265072, xor_mul(531058236, 1522941332)); - assert_eq!(3308367842185720871, xor_mul(1700999837, 3515347331)); - assert_eq!(5582146373973471156, xor_mul(3128843194, 2892662498)); - assert_eq!(5197577012378903625, xor_mul(3966451265, 3456919561)); - assert_eq!(5076235779695138180, xor_mul(3233955540, 4155667461)); - assert_eq!(5041956745231058732, xor_mul(3137053980, 3153402677)); - assert_eq!(449029540692164234, xor_mul(1948118349, 397191634)); - assert_eq!(3786442463749305066, xor_mul(1190621674, 3628889985)); - assert_eq!(3440549460014024670, xor_mul(2106866191, 3857895490)); - assert_eq!(1528962614547299152, xor_mul(1868126580, 1767828516)); - assert_eq!(2508532949574004150, xor_mul(2992004222, 1505434157)); - assert_eq!(2327634121549296275, xor_mul(3925694773, 1758870655)); - assert_eq!(7257180057129154944, xor_mul(3850715328, 3160777378)); - assert_eq!(9216621579985580286, xor_mul(3048160665, 3608126574)); - assert_eq!(5907475734858138670, xor_mul(4014836531, 3770002874)); - assert_eq!(47299776568275280, xor_mul(427576720, 206045037)); - assert_eq!(174074512819035664, xor_mul(3410244060, 119887148)); - assert_eq!(3116298418657666199, xor_mul(1271130465, 3180671159)); - assert_eq!(130740941844403068, xor_mul(1612373183, 92275332)); - assert_eq!(2227746384385250634, xor_mul(1193198319, 2119181822)); - assert_eq!(3563068769544832918, xor_mul(3221281694, 1128691149)); - assert_eq!(108980518478507848, xor_mul(860113823, 143009496)); - assert_eq!(112146113283630940, xor_mul(2816955165, 66355916)); - assert_eq!(3209498496158786286, xor_mul(3954084329, 2142877022)); - assert_eq!(6193441409059035240, xor_mul(2647124952, 2994962307)); - assert_eq!(6226869574356444159, xor_mul(3227595467, 3372069325)); - assert_eq!(4843814881447501259, xor_mul(2962522447, 3198222413)); - assert_eq!(426630101308735846, xor_mul(3846010890, 262073999)); - assert_eq!(1853798696792617694, xor_mul(566897337, 3373327502)); - assert_eq!(1966838142700480504, xor_mul(993591588, 2862230030)); - assert_eq!(3639461145036136796, xor_mul(4106490356, 1360639763)); - assert_eq!(1925534994360371342, xor_mul(1147025403, 1817816938)); - assert_eq!(3634425862933673426, xor_mul(1644186057, 2299475010)); - assert_eq!(2464111059642867566, xor_mul(1247843818, 2667617035)); - assert_eq!(2350153312285279665, xor_mul(1624158905, 4256796873)); - assert_eq!(2850531047138812302, xor_mul(4189932329, 1798351294)); - assert_eq!(1486082696691782420, xor_mul(2909702661, 585213700)); - assert_eq!(2649806316519305424, xor_mul(2086760360, 3701034034)); - assert_eq!(2170383500442791041, xor_mul(903084605, 3189606445)); - assert_eq!(1643767853711382158, xor_mul(3858601673, 1031921150)); - assert_eq!(7725199539164948432, xor_mul(4105452632, 2982393158)); - assert_eq!(3006749785472129805, xor_mul(4054198601, 2110049381)); - assert_eq!(3984594387247199320, xor_mul(2954774136, 2129671437)); - assert_eq!(5454653628742070890, xor_mul(2455422454, 2241343915)); - assert_eq!(949909218755351823, xor_mul(683140463, 1971658401)); - assert_eq!(6648710440848711212, xor_mul(2219107298, 3174795830)); - assert_eq!(4387467003412738779, xor_mul(1218197297, 4018893323)); - assert_eq!(3949143420499952336, xor_mul(1231611404, 3230742124)); - assert_eq!(3102058349658132183, xor_mul(4003938445, 1953020995)); - assert_eq!(5824364053818140888, xor_mul(3432057350, 3447619620)); - assert_eq!(402448503266966352, xor_mul(326694335, 1464707568)); - assert_eq!(283343416853086680, xor_mul(1703441535, 171480680)); - assert_eq!(173366152475041984, xor_mul(1675104601, 243296960)); - assert_eq!(1463526334944962896, xor_mul(1101672560, 1358900359)); - assert_eq!(1724958009142895972, xor_mul(1486151998, 1176283158)); - assert_eq!(323339694521048878, xor_mul(1268794622, 325573177)); - assert_eq!(133197901901887265, xor_mul(1204124321, 121339265)); - assert_eq!(7382917723094673096, xor_mul(2395289908, 3307541578)); - assert_eq!(8654315346180184172, xor_mul(2335856465, 4257754540)); - assert_eq!(4311595948954631948, xor_mul(3152244583, 1695148084)); - assert_eq!(467947919192110215, xor_mul(410485381, 1144582571)); - assert_eq!(1384759049206803106, xor_mul(1860478875, 2053250542)); - assert_eq!(3698677069390789259, xor_mul(1279301893, 3679739607)); - assert_eq!(4531388231301396529, xor_mul(1146026651, 4096482775)); - assert_eq!(4166032737587999215, xor_mul(2101349261, 2479848667)); - assert_eq!(479757380231767088, xor_mul(1597221410, 534270872)); - assert_eq!(7782016477278872683, xor_mul(4010439465, 2732134291)); - assert_eq!(1948994408556721464, xor_mul(1502469948, 2113318002)); - assert_eq!(2102159745664376400, xor_mul(2395642360, 953667038)); - assert_eq!(2642717006354016012, xor_mul(2798113475, 1572922372)); - assert_eq!(604911721254394712, xor_mul(392763210, 3037489500)); - assert_eq!(429728672387013272, xor_mul(2027601540, 500792166)); - assert_eq!(466284266395859144, xor_mul(1641644241, 287173192)); - assert_eq!(1099356420782787958, xor_mul(673397154, 1658675531)); - assert_eq!(950895133767130432, xor_mul(668641744, 1641024548)); - assert_eq!(1859758453069873974, xor_mul(617495778, 3596757131)); - assert_eq!(3115416191363345932, xor_mul(1111415988, 2849757511)); - assert_eq!(8050334533677165614, xor_mul(3199023989, 4155509078)); - assert_eq!(5895330320397640798, xor_mul(2438826278, 3020568405)); - assert_eq!(3190559650972604056, xor_mul(4051408356, 1934783030)); - assert_eq!(2335118622826822339, xor_mul(1906469141, 3651426575)); - assert_eq!(2816742440934079210, xor_mul(3520534590, 2120434815)); - assert_eq!(7139426485652885536, xor_mul(2310677648, 3421395218)); - assert_eq!(2590376858790817216, xor_mul(2306917787, 1125249344)); - assert_eq!(6294487202012800747, xor_mul(2287846107, 2763422865)); - assert_eq!(8359525168348312140, xor_mul(2881210561, 3554125644)); - assert_eq!(6117909894342257884, xor_mul(3432620892, 3258090273)); - assert_eq!(6436650438434468207, xor_mul(3308309453, 3646739867)); - assert_eq!(880951093317656186, xor_mul(484708015, 2977790766)); - assert_eq!(1414248317312558054, xor_mul(1588004195, 1453516002)); - assert_eq!(5697171718473588768, xor_mul(3393198812, 3802264920)); - assert_eq!(6614446099871830436, xor_mul(2761600581, 2518684020)); - assert_eq!(8945002808370977863, xor_mul(3698929917, 3200002627)); - assert_eq!(3336225862125073203, xor_mul(1553481479, 2147616189)); - assert_eq!(32679099365301580, xor_mul(2721265711, 14446868)); - assert_eq!(3887138410226351508, xor_mul(1179637660, 3693794039)); - assert_eq!(4547498452923665171, xor_mul(1153882173, 4065719335)); - assert_eq!(2361900330903588432, xor_mul(2434686844, 1209203772)); - assert_eq!(2080524629819565339, xor_mul(2018761491, 1314209657)); - assert_eq!(2546577658919579190, xor_mul(1808047510, 3888309297)); - assert_eq!(3764704395585504420, xor_mul(1614033174, 2668865694)); - assert_eq!(4305669791953995676, xor_mul(2972346993, 1674976988)); - assert_eq!(4360497647571473560, xor_mul(2070695446, 2263774500)); - assert_eq!(217184807489458877, xor_mul(424742517, 591044329)); - assert_eq!(2014088650827117220, xor_mul(3525440701, 574499220)); - assert_eq!(2830852220292963908, xor_mul(2909241532, 1587758627)); - assert_eq!(556966598590061799, xor_mul(270115159, 2078895953)); - assert_eq!(4770082142318552280, xor_mul(3359319032, 4065054509)); - assert_eq!(1988861666768413044, xor_mul(659322078, 3459224046)); - assert_eq!(364202173505635776, xor_mul(324918592, 1606708395)); - assert_eq!(5945478796003399675, xor_mul(3933819603, 3769154969)); - assert_eq!(6439171132929748834, xor_mul(2352118709, 3165429546)); - assert_eq!(617767329022097699, xor_mul(1297973605, 607453695)); - assert_eq!(1741785644062149091, xor_mul(1721059209, 1148203195)); - assert_eq!(5213773654996979073, xor_mul(2744368367, 3166404307)); - assert_eq!(1840861617135866370, xor_mul(2691549593, 1007234994)); - assert_eq!(3779258810997091568, xor_mul(1681056560, 2429201685)); - assert_eq!(5131409734634441709, xor_mul(2577772155, 2486518307)); - assert_eq!(600263778220748814, xor_mul(3300740794, 529174883)); - assert_eq!(7059140477185270686, xor_mul(3186873993, 3992661998)); - assert_eq!(215889863818598036, xor_mul(3987772602, 127597490)); - assert_eq!(6907707261119618328, xor_mul(3080061800, 2345370407)); - assert_eq!(1757682468643705459, xor_mul(559271605, 3304350623)); - assert_eq!(1851485148460057080, xor_mul(1066884376, 2859761397)); - assert_eq!(4440647653985702104, xor_mul(2565981335, 1919983528)); - assert_eq!(451548364804342852, xor_mul(2899997602, 268364162)); - assert_eq!(7192849386323380608, xor_mul(3016573408, 3776911764)); - assert_eq!(2671662474848282871, xor_mul(1075622309, 2490436347)); - assert_eq!(2103837083036266128, xor_mul(1654495982, 1529540760)); - assert_eq!(6929832478717489952, xor_mul(2402632232, 3356167604)); - assert_eq!(6663356815334017212, xor_mul(2495687282, 2823166734)); - assert_eq!(831238524972775156, xor_mul(1279703910, 698400438)); - assert_eq!(2714394132811664969, xor_mul(1856552189, 4284675653)); - assert_eq!(939094430713284398, xor_mul(1326010766, 812532337)); - assert_eq!(6828476440126435403, xor_mul(3222021051, 3606536657)); - assert_eq!(874437249986550928, xor_mul(4152851184, 362337483)); - assert_eq!(7473914318486340176, xor_mul(2777531641, 4110247888)); - assert_eq!(4573578983396633728, xor_mul(3116886956, 1861865440)); - assert_eq!(8408067264874841115, xor_mul(4254699181, 2666454143)); - assert_eq!(102665758690983949, xor_mul(166656421, 731389577)); - assert_eq!(3116290802993597152, xor_mul(3535717130, 1814553520)); - assert_eq!(1075801001314835648, xor_mul(470669920, 2295768770)); - assert_eq!(799105677043490186, xor_mul(482274513, 4062744746)); - assert_eq!(628331459690883792, xor_mul(2123019926, 856480408)); - assert_eq!(43528617938543256, xor_mul(20150359, 2202040680)); - assert_eq!(1759919367703070358, xor_mul(1436778690, 2036016363)); - assert_eq!(3551268864306481812, xor_mul(3323811348, 1092452769)); - assert_eq!(78459986133614048, xor_mul(1980484904, 114988044)); - assert_eq!(4690362599354536, xor_mul(113665476, 120510794)); - assert_eq!(1724855956340929567, xor_mul(583792937, 3080129991)); - assert_eq!(250063219286081792, xor_mul(309887616, 825034922)); - assert_eq!(4484720894018751571, xor_mul(1582972675, 3743506737)); - assert_eq!(129155055150900984, xor_mul(62895960, 2398198861)); - assert_eq!(7644813940101280882, xor_mul(3606622230, 2201641663)); - assert_eq!(4222071416571147124, xor_mul(2683711620, 2139692925)); - assert_eq!(7403866903426819811, xor_mul(2614571645, 3652136279)); - assert_eq!(3288023904694387728, xor_mul(4272829557, 1985390160)); - assert_eq!(743332948690662105, xor_mul(1284583189, 774967805)); - assert_eq!(1605519659285646920, xor_mul(1507146392, 1089342423)); - assert_eq!(1119737655160722323, xor_mul(444347995, 3055193465)); - assert_eq!(165300604864957136, xor_mul(2127571147, 227732784)); - assert_eq!(4227648558739649664, xor_mul(4027160970, 1263408960)); - assert_eq!(23771463911008541, xor_mul(101288679, 432883775)); - assert_eq!(5071019533961269486, xor_mul(2955447630, 3079286513)); - assert_eq!(5782285926531788288, xor_mul(2775422328, 2218228288)); - assert_eq!(1123086122057207795, xor_mul(438010733, 3050042039)); - assert_eq!(462453352622903972, xor_mul(1911404209, 400364132)); - assert_eq!(759175622207799420, xor_mul(1004676948, 2010448867)); - assert_eq!(7174566392434848652, xor_mul(2689619133, 4177649756)); - assert_eq!(8024554970815363232, xor_mul(4277251010, 2956941904)); - assert_eq!(3586796453350635613, xor_mul(3528754871, 1305153071)); - assert_eq!(716299206502621504, xor_mul(374575426, 2705855648)); - assert_eq!(2628184141572208768, xor_mul(2875985344, 1514031478)); - assert_eq!(374341695695249432, xor_mul(255529220, 4179288454)); - assert_eq!(1919739629069752160, xor_mul(1988611499, 1364577824)); - assert_eq!(202035790036497791, xor_mul(76919085, 2780898283)); - assert_eq!(1981062709390295715, xor_mul(3579392937, 582364571)); - assert_eq!(3653060100725424177, xor_mul(1125028491, 3482937479)); - assert_eq!(3255814583860007336, xor_mul(2742354920, 1237042729)); - assert_eq!(261195369002632266, xor_mul(2742550095, 109640638)); - assert_eq!(248760936616729444, xor_mul(1017373079, 390839948)); - assert_eq!(1379299000317064896, xor_mul(812412056, 4024020424)); - assert_eq!(315103690810603767, xor_mul(284171331, 1175790957)); - assert_eq!(4613580130684264260, xor_mul(2424301369, 2453403812)); - assert_eq!(8840391425047513056, xor_mul(2781180696, 3269360340)); - assert_eq!(2656300754874885776, xor_mul(2601208071, 1156852272)); - assert_eq!(1658627213996457161, xor_mul(778656109, 2177966037)); - assert_eq!(8546293918947861628, xor_mul(2642641668, 4214661471)); - assert_eq!(8858153802654084786, xor_mul(3746124070, 3026835047)); - assert_eq!(187754628109357844, xor_mul(1814572669, 234078820)); - assert_eq!(309402747996338570, xor_mul(1629033495, 509708750)); - assert_eq!(7288324631331914464, xor_mul(4088588518, 2818363856)); - assert_eq!(886742636323861553, xor_mul(556728469, 1628084533)); - assert_eq!(9159247376663192, xor_mul(172371064, 90295845)); - assert_eq!(4629491896586287332, xor_mul(3063759180, 3218559623)); - assert_eq!(1604014465397402960, xor_mul(1751689912, 1727401518)); - assert_eq!(3376729054096161204, xor_mul(1521271519, 2364588636)); - assert_eq!(2206022078489840424, xor_mul(2709085437, 822858184)); - assert_eq!(107338948033020176, xor_mul(276488144, 398096317)); - assert_eq!(1924503528045604212, xor_mul(750138329, 4110670740)); - assert_eq!(6121499544549568397, xor_mul(3693024449, 3495034445)); - assert_eq!(5477439504046660637, xor_mul(2403801031, 2531529503)); - assert_eq!(4885111907649357592, xor_mul(3822966589, 3700671672)); - assert_eq!(3240844705600759386, xor_mul(2528845171, 1349900758)); - assert_eq!(2496457627827240158, xor_mul(2167851126, 1171997741)); - assert_eq!(5589406371718614, xor_mul(2943585, 2715094678)); - assert_eq!(487941920366610576, xor_mul(1900966247, 343303728)); - assert_eq!(399663220764840562, xor_mul(207703599, 3632655030)); - assert_eq!(7106379551859402286, xor_mul(4048798807, 2902009730)); - assert_eq!(3446381326060339626, xor_mul(3966009615, 2031841566)); - assert_eq!(216398252627098741, xor_mul(76155643, 3669822315)); - assert_eq!(2565706596304335168, xor_mul(1398119192, 2703968536)); - assert_eq!(8086394062312383368, xor_mul(3380921590, 3005173212)); - assert_eq!(4336843869955734576, xor_mul(1411800844, 3487059972)); - assert_eq!(372048907370030905, xor_mul(352911171, 1192219991)); - assert_eq!(364032366825454688, xor_mul(255331280, 4247095854)); - assert_eq!(98184437105228900, xor_mul(60270850, 3758853938)); - assert_eq!(3955778875704677028, xor_mul(1457200580, 3910337369)); - assert_eq!(3522261510346046569, xor_mul(3053048277, 1893094733)); - assert_eq!(7908000676665236923, xor_mul(2961744845, 4200044799)); - assert_eq!(2094481739978900352, xor_mul(827156209, 3082414976)); - assert_eq!(4760394739250299428, xor_mul(2740680516, 2896892633)); - assert_eq!(4267402182700018264, xor_mul(2866339691, 1808189192)); - assert_eq!(273858847910920180, xor_mul(388149835, 880039820)); - assert_eq!(4590189607374278464, xor_mul(3302804032, 1455497013)); - assert_eq!(8613720796834212156, xor_mul(2997067890, 3306180558)); - assert_eq!(1989477620252852022, xor_mul(1527598498, 2093296747)); - assert_eq!(2570801956815456032, xor_mul(1483846180, 3047897480)); - assert_eq!(2791354498686132714, xor_mul(1645769618, 3910621917)); - assert_eq!(4441439740424547786, xor_mul(3451673242, 1472181449)); - assert_eq!(5950981168191011924, xor_mul(3649320573, 3691663908)); - assert_eq!(3788544125558312544, xor_mul(1325609568, 3272496289)); - assert_eq!(1528855978278406712, xor_mul(3295185196, 850897354)); - assert_eq!(6330338938177597113, xor_mul(4144943241, 4027972529)); - assert_eq!(8148877518727233608, xor_mul(2994198455, 3400937368)); - assert_eq!(2408476831841572518, xor_mul(4079797967, 1678949322)); - assert_eq!(3455329584421877766, xor_mul(1416508134, 2458107345)); - assert_eq!(5243576307918972738, xor_mul(4052998571, 3586428334)); - assert_eq!(2566913319942619485, xor_mul(2103346013, 3441236481)); - assert_eq!(1213426958996050644, xor_mul(4279275441, 827279124)); - assert_eq!(320115752068198416, xor_mul(449420912, 1915187643)); - assert_eq!(1304503038703106814, xor_mul(543356566, 2439852749)); - assert_eq!(1912989978926302732, xor_mul(2752079014, 979248994)); - assert_eq!(2944985508975587974, xor_mul(3127283805, 1309958702)); - assert_eq!(4206929653219854072, xor_mul(3261213746, 1494395996)); - assert_eq!(3523072546174689158, xor_mul(2388490182, 1696481249)); - assert_eq!(3203918533589519120, xor_mul(3071340159, 1139844400)); - assert_eq!(662488956006071364, xor_mul(3431247772, 495772683)); - assert_eq!(2858037651531688484, xor_mul(2215188100, 1295918633)); - assert_eq!(4387218581580276724, xor_mul(2639216006, 1942226646)); - assert_eq!(498932155654031328, xor_mul(405944784, 1273548918)); - assert_eq!(6795023453381633478, xor_mul(3671386971, 3429199954)); - assert_eq!(1860310628894204604, xor_mul(1517961730, 2008887134)); - assert_eq!(305172512109618180, xor_mul(455889334, 1938739726)); - assert_eq!(3079057827274749208, xor_mul(1938649690, 3839514524)); - assert_eq!(1123957492061889236, xor_mul(1621444460, 734518283)); - assert_eq!(101900646280025772, xor_mul(56231897, 3463462668)); - assert_eq!(2438307288236494876, xor_mul(3387239484, 2029232281)); - assert_eq!(7536108024986179551, xor_mul(3308408217, 2561725079)); - assert_eq!(491903049534679319, xor_mul(405417299, 1225019517)); - assert_eq!(861116868020411790, xor_mul(373345018, 2401416771)); - assert_eq!(4530618806595095782, xor_mul(4162265058, 1097159779)); - assert_eq!(1130466975104908710, xor_mul(1023272459, 1178363666)); - assert_eq!(4560708238496500214, xor_mul(1866290478, 3141197269)); - assert_eq!(2977986038634177701, xor_mul(1124230515, 2732045331)); - assert_eq!(2890650920579604670, xor_mul(1810694919, 3557257554)); - assert_eq!(2141098559569235838, xor_mul(3967341647, 541544994)); - assert_eq!(1090650768396546763, xor_mul(1244571397, 973287831)); - assert_eq!(76648113298751501, xor_mul(1843467629, 125164001)); - assert_eq!(1630004319893056151, xor_mul(3488931837, 899625555)); - assert_eq!(8565516408289496975, xor_mul(4199419477, 2628548787)); - assert_eq!(7944262515015239174, xor_mul(3981928881, 2923507110)); - assert_eq!(1323782380728260574, xor_mul(2309881050, 649335419)); - assert_eq!(434726103336114639, xor_mul(255120001, 2841923663)); - assert_eq!(6022683314687793200, xor_mul(3574654928, 3551029431)); - assert_eq!(5291537132874400579, xor_mul(3853128235, 3349812633)); - assert_eq!(5507000741441429303, xor_mul(3477940161, 3801898103)); - assert_eq!(4053683243348307546, xor_mul(4104275790, 1325785519)); - assert_eq!(472891556919672976, xor_mul(1421905882, 479118504)); - assert_eq!(1461730001037645184, xor_mul(3613418416, 902549384)); - assert_eq!(8439329632384531632, xor_mul(3118499448, 3440192922)); - assert_eq!(3729854460223476168, xor_mul(1448429818, 4193106900)); - assert_eq!(2248901375594896177, xor_mul(578239239, 4154589707)); - assert_eq!(1582385900138989488, xor_mul(1632521886, 1681108200)); - assert_eq!(3826213174957537678, xor_mul(2985503554, 2067476647)); - assert_eq!(4909776093291832, xor_mul(904063208, 14909827)); - assert_eq!(562487683858956776, xor_mul(1472406200, 406601839)); - assert_eq!(1822698994295163541, xor_mul(2526889319, 896985831)); - assert_eq!(3242258080608042872, xor_mul(1393155834, 2440699436)); - assert_eq!(843088796616274327, xor_mul(3118355093, 272758923)); - assert_eq!(350380165011701056, xor_mul(169906280, 3025609416)); - assert_eq!(6482746072603825092, xor_mul(4260026924, 3900608199)); - assert_eq!(3558339210796729558, xor_mul(3552957433, 1290321606)); - assert_eq!(2482522885543542629, xor_mul(2121276903, 3469056759)); - assert_eq!(1502276394932309348, xor_mul(1045576067, 4084075228)); - assert_eq!(3193516249629652013, xor_mul(4139743019, 1892490675)); - assert_eq!(3605494052580631340, xor_mul(3826139829, 1583278876)); - assert_eq!(317554549634165574, xor_mul(334903267, 1220227970)); - assert_eq!(6766402938426848210, xor_mul(4026847430, 3903285319)); - assert_eq!(443765735057742328, xor_mul(1515962271, 486379272)); - assert_eq!(8227958075891336276, xor_mul(2509906454, 4244895094)); - assert_eq!(1046903751408644092, xor_mul(1920800884, 586347643)); - assert_eq!(317272548618983328, xor_mul(2068761352, 406273396)); - assert_eq!(361839928091908146, xor_mul(140531805, 2802874602)); - assert_eq!(7214088363797987768, xor_mul(3510148360, 2454585431)); - assert_eq!(41268866037288417, xor_mul(1002258569, 108795945)); - assert_eq!(2213259581391720472, xor_mul(1914980152, 1299264717)); - assert_eq!(2423938935974165343, xor_mul(2125541563, 3353833533)); - assert_eq!(2571411258464574960, xor_mul(1565740688, 3204969799)); - assert_eq!(38605534328029347, xor_mul(2592201191, 18992941)); - assert_eq!(2747081803671221556, xor_mul(1861720139, 4122392524)); - assert_eq!(4020549990485267272, xor_mul(1674832919, 2421523352)); - assert_eq!(561233685089051645, xor_mul(518141587, 1156663995)); - assert_eq!(3954928896985822472, xor_mul(1826847142, 2213587004)); - assert_eq!(57497474012534722, xor_mul(767815047, 125505782)); - assert_eq!(794900642886967112, xor_mul(377306636, 2212939342)); - assert_eq!(1396445710543262962, xor_mul(875329739, 4169205118)); - assert_eq!(407288484457294736, xor_mul(1274166148, 348452196)); - assert_eq!(177056880645978584, xor_mul(156467772, 1149359674)); - assert_eq!(48661332948497602, xor_mul(933592826, 111187725)); - assert_eq!(3403835942987339714, xor_mul(1690919093, 3751886602)); - assert_eq!(6950524138415637172, xor_mul(3782520695, 3085825532)); - assert_eq!(397884239267814344, xor_mul(445894678, 1697579516)); - assert_eq!(1652318226523599758, xor_mul(2210400753, 755619374)); - assert_eq!(6796994911096741788, xor_mul(2711827428, 2614650063)); - assert_eq!(159562634417028204, xor_mul(1297268051, 155740900)); - assert_eq!(4343993304537566858, xor_mul(1645397738, 2816471793)); - assert_eq!(5933438406025843600, xor_mul(3209334269, 2665203536)); - assert_eq!(8481651695964614256, xor_mul(3796864472, 2350615594)); - assert_eq!(6210978852743727565, xor_mul(2518167671, 3170180831)); - assert_eq!(1215613455131613273, xor_mul(1713335473, 2048260969)); - assert_eq!(552429516654894365, xor_mul(3981120253, 159370081)); - assert_eq!(3900342269535305122, xor_mul(2636148018, 1698992265)); - assert_eq!(1196641610495613274, xor_mul(3775620495, 924088334)); - assert_eq!(644952771444430339, xor_mul(501991229, 3725602551)); - assert_eq!(2444836718749822859, xor_mul(1645584161, 4289702891)); - assert_eq!(609577737681480, xor_mul(158091468, 5216110)); - assert_eq!(6530618479580850624, xor_mul(2403678560, 3099755402)); - assert_eq!(3066525468095159640, xor_mul(4175297044, 2082466798)); - assert_eq!(10376218787774318, xor_mul(2063167022, 13864161)); - assert_eq!(3628817445653842582, xor_mul(1541038705, 3945936566)); - assert_eq!(2767030295921031604, xor_mul(3298795422, 1978238478)); - assert_eq!(3124075222562500130, xor_mul(3806927990, 1927641623)); - assert_eq!(4593515628373318240, xor_mul(1230139680, 3784778763)); - assert_eq!(23029050978871722, xor_mul(129863753, 524890362)); - assert_eq!(1286360944094905672, xor_mul(2997296446, 769689708)); - assert_eq!(8493922395701327108, xor_mul(4292927580, 2654191691)); - assert_eq!(7519646265602506582, xor_mul(3072940510, 4133376141)); - assert_eq!(1667046382755903168, xor_mul(818635936, 3532009806)); - assert_eq!(3403854751261818103, xor_mul(4045444515, 1990694477)); - assert_eq!(74537310785533293, xor_mul(2991814861, 49980449)); - assert_eq!(6211739113946988068, xor_mul(3081710245, 2673565556)); - assert_eq!(1687749243076882185, xor_mul(2471169803, 727707951)); - assert_eq!(4054441100824201655, xor_mul(1821271233, 2865574903)); - assert_eq!(8306871274617265746, xor_mul(2665404687, 4078416278)); - assert_eq!(3655431443632129676, xor_mul(4003712635, 1505316900)); - assert_eq!(419661221226497121, xor_mul(2926077759, 152604515)); - assert_eq!(6701922304689110160, xor_mul(3176783164, 2253953708)); - assert_eq!(6392987485494140880, xor_mul(3840596204, 4078440524)); - assert_eq!(1853657984807349558, xor_mul(2206418709, 870850670)); - assert_eq!(1533408776077285855, xor_mul(2546972581, 788260083)); - assert_eq!(1830191231324604404, xor_mul(3855661556, 801123713)); - assert_eq!(2178603539343213500, xor_mul(1353049986, 1612659550)); - assert_eq!(2537232780872824122, xor_mul(1352331499, 2760542406)); - assert_eq!(8163791836131488076, xor_mul(3606455548, 2706411189)); - assert_eq!(1100288496149320802, xor_mul(1247525914, 998922477)); - assert_eq!(2745050095963503332, xor_mul(3998496658, 1625279970)); - assert_eq!(2007649168137497473, xor_mul(2866386861, 977669821)); - assert_eq!(318304702241300895, xor_mul(1029666535, 822054601)); - assert_eq!(3002829971830215990, xor_mul(1636101326, 3351895717)); - assert_eq!(3412593204024616744, xor_mul(3984155916, 2017445318)); - assert_eq!(538895953737505723, xor_mul(348408749, 1858922847)); - assert_eq!(967952335835043541, xor_mul(1688352509, 622919369)); - assert_eq!(315820282820258322, xor_mul(1063972581, 841308730)); - assert_eq!(4070090396127280240, xor_mul(1482880904, 3401566254)); - assert_eq!(8565233277536069014, xor_mul(3199321635, 3465218738)); - assert_eq!(224756054879272989, xor_mul(3866340541, 95481633)); - assert_eq!(1365644313630637902, xor_mul(3200774075, 703227306)); - assert_eq!(1826838785381143616, xor_mul(944834416, 3106138220)); - assert_eq!(1730337662159246944, xor_mul(978057200, 3098910890)); - assert_eq!(1870402601013270085, xor_mul(1992703021, 1528770313)); - assert_eq!(2207495121372982784, xor_mul(4196070144, 574581050)); - assert_eq!(1480752793635483952, xor_mul(2828349765, 603956976)); - assert_eq!(1116023908331408616, xor_mul(513032004, 2196365082)); - assert_eq!(8113647549246332262, xor_mul(3091636074, 3299075935)); - assert_eq!(756797341121703633, xor_mul(1673520765, 842301437)); - assert_eq!(1131174835562809354, xor_mul(308336175, 3855243198)); - assert_eq!(5912423929011732624, xor_mul(3984294417, 3866835344)); - assert_eq!(39642944140571365, xor_mul(44332983, 1444943399)); - assert_eq!(2289147471396024286, xor_mul(2629714142, 983007361)); - assert_eq!(5150873468918355648, xor_mul(2962505664, 3045181677)); - assert_eq!(1886683567232970998, xor_mul(605908629, 3359233966)); - assert_eq!(8685210974498515924, xor_mul(3912467167, 2535516412)); - assert_eq!(54100315976436318, xor_mul(535204151, 168493010)); - assert_eq!(3862708117517718560, xor_mul(2392307464, 1868960004)); - assert_eq!(1236129659150626294, xor_mul(1673926943, 2076549978)); - assert_eq!(890473679075136256, xor_mul(688074176, 2123300916)); - assert_eq!(3104825440856317166, xor_mul(1985023573, 3936185686)); - assert_eq!(4129792465246017888, xor_mul(1308578152, 4128200636)); - assert_eq!(598546585681677458, xor_mul(4103074083, 435246798)); - assert_eq!(4195194777234942812, xor_mul(1442222090, 3546297462)); - assert_eq!(1186689603005453024, xor_mul(2007934452, 1786842776)); - assert_eq!(85763224323422977, xor_mul(3905717353, 51935529)); - assert_eq!(2125905792429400148, xor_mul(1420521396, 1794970969)); - assert_eq!(7594886574013839918, xor_mul(3938022211, 2749477274)); - assert_eq!(2822895860927682074, xor_mul(1522029866, 2772780537)); - assert_eq!(1544002914547342585, xor_mul(3703575487, 889024075)); - assert_eq!(7184274632418745883, xor_mul(4192465987, 2693224393)); - assert_eq!(8362762975605511714, xor_mul(3339839166, 3021798675)); - assert_eq!(341958651073118819, xor_mul(206917775, 3786399349)); - assert_eq!(3426040861808420034, xor_mul(2421035610, 1435130717)); - assert_eq!(300602294634399142, xor_mul(4015049699, 218454562)); - assert_eq!(1150542769424318323, xor_mul(285947433, 4027706955)); - assert_eq!(190164010168428222, xor_mul(117815593, 3761426702)); - assert_eq!(991974643415506982, xor_mul(2275848750, 454545709)); - assert_eq!(265459041805652440, xor_mul(2978728364, 101877090)); - assert_eq!(3631935834178032804, xor_mul(2039788147, 2768282460)); - assert_eq!(2010993643127733662, xor_mul(2327545089, 880450462)); - assert_eq!(726222233152908868, xor_mul(749645316, 1243179025)); - assert_eq!(2187342209211609004, xor_mul(661252374, 3864204354)); - assert_eq!(1328460006090375142, xor_mul(1225905479, 1085982330)); - assert_eq!(4525014405810506688, xor_mul(1390701120, 3482531063)); - assert_eq!(860563049782118685, xor_mul(462537653, 3357223689)); - assert_eq!(4217280421393841424, xor_mul(1315180072, 4245565962)); - assert_eq!(4771097447456160104, xor_mul(2579150552, 2683495875)); - assert_eq!(726917923852884045, xor_mul(3663346347, 454460179)); - assert_eq!(924237891839760592, xor_mul(525800678, 2918374488)); - assert_eq!(33457941248930314, xor_mul(47200130, 818077125)); - assert_eq!(7487623379825410304, xor_mul(3985092400, 3061367024)); - assert_eq!(4451917604570386392, xor_mul(2656917572, 1895239318)); - assert_eq!(223933442029062274, xor_mul(233459201, 1230148738)); - assert_eq!(350936311922357243, xor_mul(1055912183, 888054261)); - assert_eq!(821744094681912075, xor_mul(1957517999, 1053072557)); - assert_eq!(1681506824442221653, xor_mul(1915321089, 2115957589)); - assert_eq!(8066118979194009014, xor_mul(2440935734, 3337847745)); - assert_eq!(8332455676178691328, xor_mul(2587942336, 4112081756)); - assert_eq!(6311081256779047556, xor_mul(3127824482, 2462463778)); - assert_eq!(4861050849926498638, xor_mul(2856583418, 2813708707)); - assert_eq!(412118501672632791, xor_mul(1864590221, 413093443)); - assert_eq!(2837228334140298808, xor_mul(1866932529, 4036088504)); - assert_eq!(369959726682782063, xor_mul(2646370715, 197244877)); - assert_eq!(1924219631900387622, xor_mul(1017954682, 3078455335)); - assert_eq!(1523096706775368228, xor_mul(1027462234, 4133962666)); - assert_eq!(6052318944292123864, xor_mul(3716917912, 3675832889)); - assert_eq!(3706354363532715015, xor_mul(1123529349, 3404323627)); - assert_eq!(1771258249580110788, xor_mul(929455971, 2473751868)); - assert_eq!(6229523256495690457, xor_mul(3460896291, 3330936343)); - assert_eq!(153103417302791597, xor_mul(176639623, 1383282703)); - assert_eq!(1358253247071214540, xor_mul(2151375092, 633191751)); - assert_eq!(4451917931570624896, xor_mul(3712331088, 1512672760)); - assert_eq!(1817451173348146207, xor_mul(580846025, 3337855591)); - assert_eq!(4083337477384481714, xor_mul(2414902587, 1960404190)); - assert_eq!(1746448498110808186, xor_mul(1104771078, 1640121323)); - assert_eq!(1811749934442391677, xor_mul(537210059, 3376056803)); - assert_eq!(3122846889760556355, xor_mul(1321659661, 3036666599)); - assert_eq!(9147869923242351629, xor_mul(3678135173, 3155668777)); - assert_eq!(2453009113817020748, xor_mul(2727223935, 1364433364)); - assert_eq!(320089281842637330, xor_mul(1903440514, 438761033)); - assert_eq!(1565616127386769032, xor_mul(1788039160, 1864581491)); - assert_eq!(1036923734868458562, xor_mul(276779450, 3839540717)); - assert_eq!(134424585484511399, xor_mul(913549363, 169438029)); - assert_eq!(8716472888939175980, xor_mul(3338885205, 2783665308)); - assert_eq!(8288622766487616556, xor_mul(2922760860, 3624264149)); - assert_eq!(7835038569786921644, xor_mul(2570579526, 3450730738)); - assert_eq!(2503471391660145800, xor_mul(2377964908, 1132614382)); - assert_eq!(3928395794655800724, xor_mul(2098484404, 2969765033)); - assert_eq!(2072182000837503520, xor_mul(1519266800, 1695450982)); - assert_eq!(8265973739358637130, xor_mul(3537698594, 2726117621)); - assert_eq!(1802493032785571299, xor_mul(1032247613, 2725268375)); - assert_eq!(19619185861751454, xor_mul(10039482, 2437837899)); - assert_eq!(2215468640369760894, xor_mul(785872870, 3588761349)); - assert_eq!(3572529816541817015, xor_mul(1398253819, 4261383781)); - assert_eq!(370307757439420710, xor_mul(733144854, 571532489)); - assert_eq!(3845981760053323678, xor_mul(1734910270, 2476192753)); - assert_eq!(1484295529764415160, xor_mul(3417707480, 857640133)); - assert_eq!(128892999448872122, xor_mul(70566093, 1883284130)); - assert_eq!(5837381070791843116, xor_mul(3872595146, 3898394990)); - assert_eq!(3478736982000091976, xor_mul(1787136808, 2597168253)); - assert_eq!(4306153282790701648, xor_mul(3195871408, 1713448875)); - assert_eq!(44033129449486889, xor_mul(29672223, 3383065115)); - assert_eq!(6700480050728099263, xor_mul(3110864417, 2158105695)); - assert_eq!(6408674341283751728, xor_mul(3119310895, 2332512848)); - assert_eq!(3051318078736446972, xor_mul(2817390882, 1188559902)); - assert_eq!(1972989709924562971, xor_mul(780351859, 4095020889)); - assert_eq!(8048658988730391304, xor_mul(2172392103, 3733992152)); - assert_eq!(2433326231168527560, xor_mul(1191895996, 2314226422)); - assert_eq!(2262298967858370092, xor_mul(1670842444, 1418824969)); - assert_eq!(7803938417708341091, xor_mul(2484042097, 3328979443)); - assert_eq!(7539322157117594696, xor_mul(2333062132, 3731408138)); - assert_eq!(2705973594988999680, xor_mul(1327534528, 2310364144)); - assert_eq!(455498720733482479, xor_mul(494244741, 1523229411)); - assert_eq!(4003355075929112936, xor_mul(2003101608, 2951934137)); - assert_eq!(145619321149625216, xor_mul(105857344, 4119966742)); - assert_eq!(1322726589776158064, xor_mul(1413122850, 1516370232)); - assert_eq!(4281575980138241722, xor_mul(2004761533, 2189949122)); - assert_eq!(16281594880419440, xor_mul(696430160, 28229099)); - assert_eq!(6774353018767117994, xor_mul(3263840733, 3574506962)); - assert_eq!(25908512765000440, xor_mul(23153497, 1167041208)); - assert_eq!(119772304291037529, xor_mul(266315289, 793442625)); - assert_eq!(3876561449444878992, xor_mul(1969783400, 2751698474)); - assert_eq!(235128318431245156, xor_mul(3248079130, 82986442)); - assert_eq!(7492929719824884655, xor_mul(3538012839, 2505512153)); - assert_eq!(55196351724228315, xor_mul(379005127, 241792773)); - assert_eq!(9106944950460834758, xor_mul(2375564262, 4113610993)); - assert_eq!(173999956604907592, xor_mul(2054170120, 234339529)); - assert_eq!(944771168620951036, xor_mul(2376235561, 461253276)); - assert_eq!(6746362651807636992, xor_mul(3252394112, 3554295292)); - assert_eq!(2136327602749129599, xor_mul(1167588285, 1890022299)); - assert_eq!(647259156825987205, xor_mul(1235154857, 667525837)); - assert_eq!(181347495823061120, xor_mul(3044547080, 76587536)); - assert_eq!(1541749083112940234, xor_mul(1401157942, 1204429947)); - assert_eq!(627036784648830094, xor_mul(2556878738, 302767359)); - assert_eq!(1490452281418649367, xor_mul(2951928321, 572172567)); - assert_eq!(2606982472231538634, xor_mul(1947010026, 3413349457)); - assert_eq!(3199162885566252185, xor_mul(1236031391, 2799143243)); - assert_eq!(373308689736776416, xor_mul(1806409304, 442344020)); - assert_eq!(775672694251729568, xor_mul(1011578373, 2049481248)); - assert_eq!(2062439525931452445, xor_mul(974974257, 2337223277)); - assert_eq!(1604548751928611850, xor_mul(4263530758, 984682115)); - assert_eq!(1177305211198487096, xor_mul(1063015708, 3251055618)); - assert_eq!(4092786701660439636, xor_mul(1871663310, 2897198798)); - assert_eq!(601898756794109321, xor_mul(953677933, 1874629781)); - assert_eq!(7182338930138762251, xor_mul(2171635965, 3332266975)); - assert_eq!(6892263101861225161, xor_mul(3129799999, 2215848091)); - assert_eq!(1610879334455702892, xor_mul(1752808402, 1722448070)); - assert_eq!(5954098380190959489, xor_mul(3886730673, 3984357169)); - assert_eq!(1372560992868278988, xor_mul(559705683, 2647445124)); - assert_eq!(2152711712927790556, xor_mul(2482179638, 1016054794)); - assert_eq!(1515787389000267590, xor_mul(2222408362, 726886703)); - assert_eq!(189627500764286944, xor_mul(172005979, 1207000992)); - assert_eq!(4215965669892889695, xor_mul(2346241635, 1935250581)); - assert_eq!(430287207034939114, xor_mul(407571253, 1810727554)); - assert_eq!(1597374713353464392, xor_mul(3729850776, 806227895)); - assert_eq!(1880883457279792240, xor_mul(636980431, 3440218512)); - assert_eq!(19222848170558640, xor_mul(490631236, 116338668)); - assert_eq!(6794589931404934436, xor_mul(3433275655, 3658451724)); - assert_eq!(2437006998208884613, xor_mul(2549287105, 1225503813)); - assert_eq!(836725431393993716, xor_mul(1351722692, 667251213)); - assert_eq!(778971418295057182, xor_mul(2002949919, 973255522)); - assert_eq!(1824537749281412064, xor_mul(777323632, 3780285522)); - assert_eq!(4194917442664844516, xor_mul(3938911532, 1101896703)); - assert_eq!(4594741650119219018, xor_mul(1090257110, 4267525579)); - assert_eq!(2581741321352371963, xor_mul(1367437265, 2784104459)); - assert_eq!(3957829679827338684, xor_mul(4233798023, 1517104100)); - assert_eq!(756845859427052899, xor_mul(504492337, 4088732467)); - assert_eq!(2918282873851881258, xor_mul(2121232373, 4061750210)); - assert_eq!(3654504162672880726, xor_mul(1789347819, 2526872194)); - assert_eq!(2212868445855255812, xor_mul(4150945879, 551586860)); - assert_eq!(3103486486350451421, xor_mul(2066571807, 4084249991)); - assert_eq!(8607273441719426679, xor_mul(2282233179, 3773178821)); - assert_eq!(1156509613521658418, xor_mul(709954394, 2745522693)); - assert_eq!(252077335585159584, xor_mul(189518072, 2094109404)); - assert_eq!(5062083683181171394, xor_mul(3962498385, 3751106146)); - assert_eq!(3010273305490828905, xor_mul(1227337335, 3019767955)); - assert_eq!(574655313858769572, xor_mul(647047805, 1006590612)); - assert_eq!(4569600963837430108, xor_mul(1334926012, 3949705865)); - assert_eq!(2735819427681789776, xor_mul(1204260345, 2571143888)); - assert_eq!(3974865897512847200, xor_mul(1188267424, 3594501727)); - assert_eq!(7310653617202749736, xor_mul(3752244696, 2586733723)); - assert_eq!(2180000542698929556, xor_mul(2282816124, 1064390863)); - assert_eq!(757270560660105761, xor_mul(4098734879, 518883587)); - assert_eq!(1397504678043332472, xor_mul(3680025976, 1007719105)); - assert_eq!(201012468274968121, xor_mul(500330171, 1049640015)); - assert_eq!(1643195608657045224, xor_mul(1211401672, 1361787525)); - assert_eq!(1438226678867312887, xor_mul(582596071, 2487536817)); - assert_eq!(1626403113695771767, xor_mul(1682129547, 1758180149)); - assert_eq!(4967375577310524888, xor_mul(3217776478, 3155765748)); - assert_eq!(1021827422708145586, xor_mul(3455753262, 383685155)); - assert_eq!(1620087579293700270, xor_mul(1436282169, 1333572990)); - assert_eq!(5439846019754306240, xor_mul(2639863084, 2315606544)); - assert_eq!(3676992219044753402, xor_mul(1202592450, 3298529821)); - assert_eq!(295088102467792584, xor_mul(2640416745, 164556168)); - assert_eq!(420015236428626942, xor_mul(1563437339, 270019450)); - assert_eq!(4171570731399781654, xor_mul(1182897686, 4023304321)); - assert_eq!(313930817850152872, xor_mul(3181491466, 197323460)); - assert_eq!(2120144195882588856, xor_mul(3565200957, 729448088)); - assert_eq!(4135138222079530544, xor_mul(2025811824, 2673130909)); - assert_eq!(974728633115924378, xor_mul(1856250370, 565409485)); - assert_eq!(7012021215195861444, xor_mul(2941085754, 4118018426)); - assert_eq!(4588099163818648368, xor_mul(1386294518, 3420932040)); - assert_eq!(8088587275526614880, xor_mul(3032369406, 3434123472)); - assert_eq!(1777061508699445812, xor_mul(2558922366, 884720302)); - assert_eq!(2852489885718700872, xor_mul(3616495155, 2083420856)); - assert_eq!(6039862574505537392, xor_mul(2152668650, 2818357848)); - assert_eq!(2012276748606470592, xor_mul(612330075, 3333688640)); - assert_eq!(4826579945688757288, xor_mul(4076191460, 3387325242)); - assert_eq!(2954762755339698144, xor_mul(2241130016, 1350138927)); - assert_eq!(6281724276907374272, xor_mul(3617096354, 3729266016)); - assert_eq!(3009040870412314168, xor_mul(2003113772, 3875979722)); - assert_eq!(115984953714082292, xor_mul(103828654, 1204044126)); - assert_eq!(1201962710671725270, xor_mul(1502623546, 1599217823)); - assert_eq!(1768363152935762540, xor_mul(671397894, 4210238226)); - assert_eq!(3356298063062783748, xor_mul(3441635541, 1874361620)); - assert_eq!(191715993548523838, xor_mul(432977822, 814281457)); - assert_eq!(6952761006361384478, xor_mul(2897292062, 4122385281)); - assert_eq!(8791194092176411538, xor_mul(2565668835, 3859055694)); - assert_eq!(444859417520974296, xor_mul(459423377, 1262456920)); - assert_eq!(58842996590135436, xor_mul(2325120661, 29264828)); - assert_eq!(1690509597531888352, xor_mul(832106592, 3557011149)); - assert_eq!(3738965538328709322, xor_mul(1376307282, 4116775085)); - assert_eq!(3226502809094447705, xor_mul(1217804729, 2795769569)); - assert_eq!(599870617048294504, xor_mul(1881778757, 924486472)); - assert_eq!(356346683979125708, xor_mul(2800565998, 189463130)); - assert_eq!(339452588688686662, xor_mul(3963108683, 213057330)); - assert_eq!(3137989196724614390, xor_mul(1929097589, 3765384686)); - assert_eq!(413131240504769782, xor_mul(815413578, 908041479)); - assert_eq!(1984222194355718168, xor_mul(4068422040, 780383249)); - assert_eq!(8449006204868051540, xor_mul(3477426044, 3122989471)); - assert_eq!(1003523456326983103, xor_mul(2835039971, 491446709)); - assert_eq!(245177496324409516, xor_mul(1193399302, 219615282)); - assert_eq!(6726709819786389969, xor_mul(3343756681, 3572602009)); - assert_eq!(2129695280915727138, xor_mul(3488392722, 797874265)); - assert_eq!(3711490030387662669, xor_mul(1472834911, 4195298423)); - assert_eq!(2305461512415025554, xor_mul(4116815943, 601761798)); - assert_eq!(1022204836156138048, xor_mul(1383962014, 875871584)); - assert_eq!(6124058566554237137, xor_mul(4026455285, 3995080245)); - assert_eq!(1743522333418554499, xor_mul(1748966301, 1311047063)); - assert_eq!(3828807313491477561, xor_mul(3109604251, 2105581295)); - assert_eq!(6879005257989111578, xor_mul(3466294670, 3687327535)); - assert_eq!(5934422285573512099, xor_mul(3337410757, 3251080607)); - assert_eq!(271632400619818372, xor_mul(2528046633, 121876516)); - assert_eq!(5618458075617706108, xor_mul(2353193135, 2523769668)); - assert_eq!(6032883871238494250, xor_mul(3795834743, 3958843630)); - assert_eq!(4348234047250267664, xor_mul(3329331112, 1382636938)); - assert_eq!(6484124020093919852, xor_mul(3646068676, 3298564363)); - assert_eq!(2162569950879848392, xor_mul(2351508120, 1041802183)); - assert_eq!(1149438359126280378, xor_mul(1593340915, 907279222)); - assert_eq!(4221264735792051800, xor_mul(3473389753, 1567602712)); - assert_eq!(322951549153389311, xor_mul(1848902261, 498627043)); - assert_eq!(2101141419287719338, xor_mul(1937106203, 1149525974)); - assert_eq!(6656628124022890400, xor_mul(3169621577, 2240684704)); - assert_eq!(3865927343168664368, xor_mul(2988653880, 2065372090)); - assert_eq!(3763738094152388512, xor_mul(3941842616, 1349670076)); - assert_eq!(5500238662055357124, xor_mul(3396275652, 3860786625)); - assert_eq!(6051137854919350040, xor_mul(4237055080, 4149691463)); - assert_eq!(8181209536022266231, xor_mul(2922105553, 3697758535)); - assert_eq!(5246041569354373240, xor_mul(3088748393, 2795236536)); - assert_eq!(795539680939686992, xor_mul(660139075, 1434701872)); - assert_eq!(4310391603222254285, xor_mul(1278383903, 4279467703)); - assert_eq!(1356748400436012116, xor_mul(622969790, 2188943934)); - assert_eq!(2862999109564543010, xor_mul(2074366169, 3664002066)); - assert_eq!(8016245604185390044, xor_mul(3938658919, 2833680580)); - assert_eq!(438342136076279696, xor_mul(170664996, 4265799108)); - assert_eq!(511417529224782932, xor_mul(3818108569, 135071924)); - assert_eq!(2594329379751419479, xor_mul(1762016811, 4129238325)); - assert_eq!(166592537077289776, xor_mul(1808881342, 252697000)); - assert_eq!(1844417793911104709, xor_mul(1101557051, 1729092027)); - assert_eq!(2427902568544198179, xor_mul(3276514261, 2086868271)); - assert_eq!(5674302908067269592, xor_mul(3840088572, 3483581978)); - assert_eq!(6098436633657858032, xor_mul(3924213816, 3909043090)); - assert_eq!(8498808094963741067, xor_mul(3640756479, 2815391645)); - assert_eq!(3564628244928381730, xor_mul(1312701182, 3571368499)); - assert_eq!(118440019183248808, xor_mul(105317505, 1231933864)); - assert_eq!(2752380897181354725, xor_mul(2192467037, 1292436377)); - assert_eq!(5318920590358619788, xor_mul(4114099380, 3554377959)); - assert_eq!(1669231363997182072, xor_mul(1032824101, 3987574552)); - assert_eq!(2179232081886795065, xor_mul(907080859, 3083391727)); - assert_eq!(4108623040475691154, xor_mul(2998238671, 1721007446)); - assert_eq!(7919547175547830232, xor_mul(2287146012, 3604055114)); - assert_eq!(1134464629937020271, xor_mul(1082363119, 1048955521)); - assert_eq!(204645315690484142, xor_mul(2239805873, 93118862)); - assert_eq!(2352414531855514652, xor_mul(2524033954, 1265568366)); - assert_eq!(43971730097200738, xor_mul(62947523, 1878762078)); - assert_eq!(5774656200657986464, xor_mul(3327256464, 3323586826)); - assert_eq!(2317851944644201642, xor_mul(3335695027, 2081292550)); - assert_eq!(1410327517683266240, xor_mul(1560002587, 1415285824)); - assert_eq!(2353637492524558322, xor_mul(3830863346, 1858732289)); - assert_eq!(1727916508081186016, xor_mul(1884194576, 2141511406)); - assert_eq!(4545204708067040200, xor_mul(2256338518, 2082339708)); - assert_eq!(1099346732573237091, xor_mul(3492588511, 396506181)); - assert_eq!(4113751652266832971, xor_mul(1964016451, 2293055737)); - assert_eq!(1235532712581488168, xor_mul(1983855406, 1813729692)); - assert_eq!(437969293200789756, xor_mul(1524404398, 470578162)); - assert_eq!(6813520240937145803, xor_mul(3820723415, 4292070597)); - assert_eq!(427683543762119604, xor_mul(2952741726, 157447118)); - assert_eq!(4068006608723057895, xor_mul(3425685375, 1526663337)); - assert_eq!(6235423430617878844, xor_mul(3429980890, 3318616758)); - assert_eq!(1764396741863418496, xor_mul(1875904924, 1255806176)); - assert_eq!(8058874196613276225, xor_mul(2330845361, 3514366961)); - assert_eq!(7670253288968233269, xor_mul(2902298917, 3828438865)); - assert_eq!(7713452682525289398, xor_mul(3450079054, 2478937125)); - assert_eq!(2321762543005257815, xor_mul(3971444723, 1783469149)); - } - - #[test] - fn func1test() { - assert_eq!(11798831065491430583, h(3463795518, 1682485247)); - assert_eq!(448858639501164953, h(960998136, 3442002022)); - assert_eq!(4331216232566681503, h(351187803, 2185945601)); - assert_eq!(6501943885585729174, h(3084014163, 912127940)); - assert_eq!(2773586452911195143, h(3331261599, 832118177)); - assert_eq!(628282543568432452, h(3183730720, 1526081701)); - assert_eq!(10304735604047663458, h(2898354542, 3213600473)); - assert_eq!(2315370810697976640, h(3620175596, 4229168685)); - assert_eq!(11083908256077353281, h(3101298314, 2777662723)); - assert_eq!(1049535453269404908, h(697606818, 58376940)); - assert_eq!(9099392518634985681, h(2281253821, 448345156)); - assert_eq!(11907299657269887144, h(1944100306, 1005002010)); - assert_eq!(18139734815714175271, h(1942570708, 3368934703)); - assert_eq!(1062447846124745127, h(3917100718, 3641676443)); - assert_eq!(417402990515385795, h(2273104063, 1591049751)); - assert_eq!(4610956232650099465, h(915009791, 3424846050)); - assert_eq!(4632634587732872395, h(347267775, 3096301890)); - assert_eq!(8145395893120941012, h(3292286689, 1839377893)); - assert_eq!(2027385485099641182, h(450591296, 3078598150)); - assert_eq!(6716486476978567051, h(2143937553, 3348758988)); - assert_eq!(8198866944461250122, h(3018854470, 3889192467)); - assert_eq!(11553806339277083673, h(1539512006, 2081336392)); - assert_eq!(3330621345914728912, h(3249005184, 2848346678)); - assert_eq!(2017804432676575258, h(2813387773, 345588747)); - assert_eq!(14595500749209015335, h(1741339163, 1366337508)); - assert_eq!(10297655684670651358, h(3726105746, 1592824540)); - assert_eq!(17582718239981798304, h(944533733, 159392513)); - assert_eq!(3805337247841405538, h(1736782229, 3675346013)); - assert_eq!(3020134169454795737, h(1816111867, 1015431153)); - assert_eq!(11261338510846048252, h(1228907531, 378580379)); - assert_eq!(5050542971941349005, h(3569690671, 2362083614)); - assert_eq!(9708258165684070599, h(3477213620, 3564168958)); - assert_eq!(305026462605588943, h(3774252425, 2324069875)); - assert_eq!(7389524862532086589, h(4025895326, 3447594450)); - assert_eq!(5501000178805554808, h(2566538462, 3057776716)); - assert_eq!(5443709636142862360, h(3467975414, 1642971290)); - assert_eq!(12799044778905477953, h(395172703, 2859831371)); - assert_eq!(14656588923225874652, h(3285326579, 1892500115)); - assert_eq!(8008118761937744849, h(800637690, 3507769133)); - assert_eq!(12124157006316465741, h(597363944, 4199822201)); - assert_eq!(18047019697308800918, h(1364679108, 493190167)); - assert_eq!(10571166715192387429, h(2930362386, 2610687963)); - assert_eq!(1994499305336764829, h(3567828522, 84275490)); - assert_eq!(7418908198762244633, h(1037230963, 2717520219)); - assert_eq!(5452796367047227709, h(2675210197, 1275728616)); - assert_eq!(15473779213248193476, h(2514441382, 3332966386)); - assert_eq!(15796997115634043006, h(2369700278, 3199619927)); - assert_eq!(11402557456891929028, h(3367457877, 3230470763)); - assert_eq!(6835536980872862161, h(1306487569, 3253890516)); - assert_eq!(11467735224534222612, h(3943542341, 1681756425)); - assert_eq!(1475101851310807018, h(2498152871, 2876706900)); - assert_eq!(18179994962409491574, h(1782315350, 3779560764)); - assert_eq!(992376868483489270, h(208687741, 3099564482)); - assert_eq!(7496704662186028550, h(4286428893, 1762584453)); - assert_eq!(3048486413080026187, h(4220403443, 1302445672)); - assert_eq!(2697521928737745324, h(3700790948, 1404603133)); - assert_eq!(3776917783462454246, h(3418006820, 4205067295)); - assert_eq!(7925713370373496634, h(2634361755, 2433583492)); - assert_eq!(10271614446877954159, h(1221220233, 1666949297)); - assert_eq!(885713519205033657, h(1411971418, 1568422082)); - assert_eq!(11700888629561365643, h(941730219, 105589570)); - assert_eq!(14887164959913630440, h(137958355, 1591971824)); - assert_eq!(1167079093766082498, h(1872134170, 427167400)); - assert_eq!(13953609487055404318, h(3187215651, 4176473865)); - assert_eq!(10692041568399158725, h(3614611815, 1836680903)); - assert_eq!(11463095029526131574, h(1701800384, 1448715840)); - assert_eq!(4547087054263210229, h(3552467688, 2656183881)); - assert_eq!(5377035043274396886, h(2380145620, 154837088)); - assert_eq!(14584488316805966019, h(3768076343, 3890514226)); - assert_eq!(16011234068864860434, h(702062132, 4202662539)); - assert_eq!(9220688519894226035, h(3898276141, 947574382)); - assert_eq!(14497053175144133245, h(3963535759, 3409647466)); - assert_eq!(17732239296035734458, h(2791478715, 904408856)); - assert_eq!(2503452673785104063, h(4004260463, 1275381366)); - assert_eq!(15253234983278921033, h(2779315586, 2488033918)); - } } \ No newline at end of file diff --git a/src/bin/main.rs b/src/bin/main.rs new file mode 100644 index 0000000..9f5fad8 --- /dev/null +++ b/src/bin/main.rs @@ -0,0 +1,54 @@ +use std::env; +use std::fmt::Display; +use std::process::ExitCode; +use lib::submit_with_name; + +fn main() -> ExitCode { + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("Usage: main NAME"); + return ExitCode::FAILURE; + } + + let name = args[1].clone(); + + 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()); + + println!("n = {n}"); + println!("x = {x}"); + + ExitCode::SUCCESS +} + +fn submit_or_fail(name: &str, n: T1, x: T2) { + match submit_with_name(name, n, x) { + Ok(_) => println!("Success."), + Err(err) => println!("Failure: {}", err), + } +} \ No newline at end of file diff --git a/src/lib/challenges/c1_welcome.rs b/src/lib/challenges/c1_welcome.rs new file mode 100644 index 0000000..e85bbaa --- /dev/null +++ b/src/lib/challenges/c1_welcome.rs @@ -0,0 +1,3 @@ +pub fn solve() -> (u64, u64) { + (10000, 4) +} \ No newline at end of file diff --git a/src/lib/challenges/c2_these_numbers_are_big.rs b/src/lib/challenges/c2_these_numbers_are_big.rs new file mode 100644 index 0000000..1c11847 --- /dev/null +++ b/src/lib/challenges/c2_these_numbers_are_big.rs @@ -0,0 +1,23 @@ +use std::sync::LazyLock; +use std::str::FromStr; +use rug::Integer; +use rug::integer::Order; +use sha2::{Sha256, Digest}; + +static M: LazyLock = LazyLock::new(|| Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap()); +static E: LazyLock = LazyLock::new(|| 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) +} \ No newline at end of file diff --git a/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs b/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs new file mode 100644 index 0000000..ae07a25 --- /dev/null +++ b/src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs @@ -0,0 +1,90 @@ +use rug::Integer; +use std::collections::HashMap; +use tqdm::tqdm; + +/// the modul of the discrete logarithm +const P: u64 = 12345679943u64; + +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 tqdm(0..10_000) { + n += 1; + x = log(42, 1 + (x + n) % (P - 1), P).unwrap(); + } + + (n, Integer::from(x)) +} + +/// Computes the discrete logarithm of `b` to the base `g` modulo `m` using the Baby-Step-Giant-Step algorithm. +fn log(g: u64, b: u64, m: u64) -> Option { + 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 +} + +/// Computes the `k`-th power of `a` modulo `m`. +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); + } +} \ No newline at end of file diff --git a/src/lib/challenges/c4_broken_proof_of_work.rs b/src/lib/challenges/c4_broken_proof_of_work.rs new file mode 100644 index 0000000..7bbd299 --- /dev/null +++ b/src/lib/challenges/c4_broken_proof_of_work.rs @@ -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) +} \ No newline at end of file diff --git a/src/lib/challenges/c5_what_the_bf.rs b/src/lib/challenges/c5_what_the_bf.rs new file mode 100644 index 0000000..518683a --- /dev/null +++ b/src/lib/challenges/c5_what_the_bf.rs @@ -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) +} + +fn f(mut x: u128) -> u128 { + 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 + + x = x * A % B; + x = (x * C + D) / B; + x +} \ No newline at end of file diff --git a/src/lib/challenges/c6_automation_is_not_enough.rs b/src/lib/challenges/c6_automation_is_not_enough.rs new file mode 100644 index 0000000..304f2f3 --- /dev/null +++ b/src/lib/challenges/c6_automation_is_not_enough.rs @@ -0,0 +1,21 @@ +use rug::Integer; +use std::str::FromStr; +use std::sync::LazyLock; + +const START: u64 = 1_000_000_000_000u64; +const LIMIT: u64 = 10_000_000_000_000_000u64; + +static M: LazyLock = LazyLock::new(|| Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap()); +static A: LazyLock = LazyLock::new(|| Integer::from_str("10729297455904899337681752672816753703351288544833760635567859176397566160330812285369370751389224534974913042757043771146367160829669925123791471756026119030734890865062863499420767799283504416995775836275660636668989077836006690621539265605").unwrap()); +static B: LazyLock = LazyLock::new(|| Integer::from_str("4997609466256208183077203585670710326160976219126614124062259398288517298185253986607627790890962248558793881836308854443463332741665631247256917127102588793451033551034614994254514161235462726178612824897626185944163885786520174491419225456").unwrap()); + +pub fn solve(n: u64, x: Integer) -> (u64, Integer) { + assert_eq!(n, START); + + let mut x = x; + x = (x + &*A) % &*M; + x = x * 2 % &*M; + x = (x + &*B) % &*M; + + (LIMIT, x) +} \ No newline at end of file diff --git a/src/lib/challenges/c7_weird_assembly_machine.rs b/src/lib/challenges/c7_weird_assembly_machine.rs new file mode 100644 index 0000000..520baf6 --- /dev/null +++ b/src/lib/challenges/c7_weird_assembly_machine.rs @@ -0,0 +1,132 @@ +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::str::FromStr; +use std::sync::LazyLock; +use rug::Integer; + +static DATA: LazyLock> = LazyLock::new(|| { + 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) = h_n(n, x, LIMIT - n); + (n, Integer::from(x)) +} + +fn h(x: u64, n: u64) -> u64 { + g(sub(f(x), n)) +} + +pub fn h_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 f(x: u64) -> u64 { + evaluate(x, &DATA[..128]) +} + +fn g(x: u64) -> u64 { + evaluate(x, &DATA[128..]) +} + +/// Quickly computes [`f`](f)([`g`](g)(x)). +fn fg(x: u64) -> u64 { + !x.rotate_left(17) +} + +/// Computes [`fg`](fg)(...[`fg`](fg)(x)...) where [`fg`] is applied `n` times. +fn fg_n(mut x: u64, n: u64) -> u64 { + for _ in 0..n%64 { + x = fg(x); + } + x +} + +/// Computes the sum from `i = 1` to `k` over `fg^(k-i)(n + i)`. +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 +} + +/// Quickly computes `fg_sum` when `k` is divisible by `192`. +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 +} + +/// Evaluates a polynomial over `GF(2)[X] / (X^64 + 1)` +fn evaluate(x: u64, data: &[u64]) -> u64 { + let mut out = 0; + for i in 0..data.len() { + out = xor_mul(out, x) ^ data[i]; + } + out +} + +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) +} + +#[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 + } +} \ No newline at end of file diff --git a/src/lib/challenges/mod.rs b/src/lib/challenges/mod.rs new file mode 100644 index 0000000..316df95 --- /dev/null +++ b/src/lib/challenges/mod.rs @@ -0,0 +1,7 @@ +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; \ No newline at end of file diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 5cb7a2c..209100c 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -1,4 +1,5 @@ -use anyhow::{Result, anyhow}; +#![allow(dead_code)] +use anyhow::{anyhow, Result}; use json::JsonValue; use std::fmt::Display; use std::sync::mpsc; @@ -7,19 +8,41 @@ use std::thread; use std::thread::JoinHandle; use std::time::Instant; +pub mod challenges; + const USER_NAME: &str = "Jonah"; -pub fn compute_async(mut function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static ) -> R { - let (tx, jh1) = spawn_submission_thread(); - let jh2 = thread::spawn(move || { - function(tx) - }); - - jh1.join().unwrap(); - jh2.join().unwrap() +pub fn compute_async< + T1: Display + Send + 'static, + T2: Display + Send + 'static, + R: Send + 'static +>( + function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static +) -> R { + compute_async_with_name(USER_NAME, function) } -pub fn spawn_submission_thread() -> (Sender<(T1, T2)>, JoinHandle<()>) { + +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 mut t = Instant::now(); @@ -28,7 +51,7 @@ pub fn spawn_submission_thread {} Err(err) => eprintln!("{:?}", err), }; @@ -37,8 +60,23 @@ pub fn spawn_submission_thread(n: T1, x: T2) -> Result> { - let url = format!("https://button.qedaka.de/server.php?name={USER_NAME}&n={n}&x={x}"); +pub fn submit< + T1: Display + Send, + T2: Display + Send +>( + n: T1, x: T2 +) -> Result> { + 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> { + 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()?; match json::parse(&body)? { JsonValue::Object(obj) => {