|
| 1 | +Writeup for crypto/cyanocitta-cristata-cyanotephra-but-fixed |
| 2 | + |
| 3 | + |
| 4 | +# Problem: |
| 5 | +Only the ciphertext has changed from the original challenge. |
| 6 | + |
| 7 | +The Blue Jay (Cyanocitta cristata) is a passerine bird in the family Corvidae, native to North America. It is resident through most of eastern and central United States and southern Canada, although western populations may be migratory. It breeds in both deciduous and coniferous forests, and is common near and in residential areas. It is predominately blue with a white chest and underparts, and a blue crest. It has a black, U-shaped collar around its neck and a black border behind the crest. Sexes are similar in size and plumage, and plumage does not vary throughout the year. Four subspecies of the Blue Jay are recognized. |
| 8 | +Downloads: [output.txt] [cyanocitta-cristata-cyanotephra.sage] |
| 9 | + |
| 10 | + |
| 11 | +# Solution: |
| 12 | +From the category of this problem, we know that it is a crypto problem, so let's download both [output.txt] and [cyanocitta-cristata-cyanotephra.sage]. Opening both |
| 13 | + |
| 14 | +-[output.txt]: |
| 15 | +[(26, 66, 70314326037540683861066), (175, 242, 1467209789992686137450970), (216, 202, 1514632596049937965560228), (13, 227, 485439858137512552888191), (1, 114, 112952835698501736253972), (190, 122, 874047085530701865939630), (135, 12, 230058131262420942645110), (229, 220, 1743661951353629717753164), (193, 81, 704858158272534244116883)] |
| 16 | +886191939093 589140258545 |
| 17 | +19440293474977244702108989804811578372332250 |
| 18 | + |
| 19 | +-[cyanocitta-cristata-cyanotephra.sage]: |
| 20 | +``` |
| 21 | +import random |
| 22 | +var("x y") |
| 23 | +flag = int(open('flag.txt','rb').read().hex(),16) |
| 24 | +xs = [random.randint(1,256) for i in range(9)] |
| 25 | +ys = [random.randint(1,256) for i in range(9)] |
| 26 | +assert not any([xs[i]==ys[i] for i in range(9)]) |
| 27 | +c = [random.randint(1,2^64) for i in range(len(xs))] |
| 28 | +f(x,y)=c[0]*x^2+c[1]*y^2+c[2]*x*y+c[3]*x+c[4]*y+c[5] |
| 29 | +solns = [int(f(xs[i],ys[i])) for i in range(len(xs))] |
| 30 | +print([(xs[i],ys[i],solns[i]) for i in range(9)]) |
| 31 | +a,b = random.randint(1,2^40),random.randint(1,2^40) |
| 32 | +print(a,b) |
| 33 | +print((int(f(a,b)))^^flag) |
| 34 | +``` |
| 35 | + |
| 36 | +-Let's breakdown [cyanocitta-cristata-cyanotephra.sage]: |
| 37 | +xs = [random.randint(1,256) for i in range(9)] |
| 38 | +The "xs" values create the first 9 values in each list. Let's group the xs values together from [output.txt] and put it in a matrix: |
| 39 | +xs = [26, 175, 216, 13, 1, 190, 135, 229, 193] |
| 40 | +Let's do the same for ys |
| 41 | +ys = [66, 242, 202, 227, 114, 122, 12, 220, 81] |
| 42 | + |
| 43 | +solns = [int(f(xs[i],ys[i])) for i in range(len(xs))] |
| 44 | +For "solns", we get the last 9 values in each list. This is found by f(x,y)=c[0]*x^2+c[1]*y^2+c[2]*x*y+c[3]*x+c[4]*y+c[5] equation. |
| 45 | + |
| 46 | +To find the values of c[0], c[1], c[2], c[3], c[4], c[5] we can create a system of equations by substiting 6 values of xs and 6 values of ys into the f(x,y) function. Let's change each c value to a variable. |
| 47 | +c[0]=a | c[1]=b | c[2]=c | c[3]=d | c[4]=e | c[5]=f |
| 48 | +Our 6 equations: |
| 49 | +``` |
| 50 | +26**2a + 66**2b + 22*66c + 26d + 66e + f = 70314326037540683861066 |
| 51 | +175**2a + 242**2b + 175*242c + 175d + 242e + f = 1467209789992686137450970 |
| 52 | +216**2a + 202**2b + 216*202c + 216d + 202e + f = 1514632596049937965560228 |
| 53 | +13**2a + 227**2b + 13*227c + 13d + 227e + f = 485439858137512552888191 |
| 54 | +1a + 114**2b + 114c + 1d + 114e + f = 112952835698501736253972 |
| 55 | +190**2a + 122**2b + 122*190c + 190d + 122e + f = 874047085530701865939630 |
| 56 | +``` |
| 57 | + |
| 58 | +Now we're ready to solve for the a,b,c,d,e,f. I used this solve script with mpmath and npumpy after putting each equation into matrix form: |
| 59 | +``` |
| 60 | +from mpmath import * |
| 61 | +import numpy as np |
| 62 | +
|
| 63 | +mp.prec = 1000 |
| 64 | +mp.dps = 1000 |
| 65 | +mp.pretty = False |
| 66 | +
|
| 67 | +print(mp) |
| 68 | +
|
| 69 | +A = matrix([[mpf(26**2), mpf(66**2), mpf(22*66), mpf(26), mpf(66), mpf(1)], |
| 70 | +[mpf(175**2), mpf(242**2), mpf(175*242), mpf(175), mpf(242), mpf(1)], |
| 71 | +[mpf(216**2), mpf(202**2), mpf(216*202), mpf(216), mpf(202), mpf(1)], |
| 72 | +[mpf(13**2), mpf(227**2), mpf(13*227), mpf(13), mpf(227), mpf(1)], |
| 73 | +[mpf(1), mpf(114**2), mpf(114), mpf(1), mpf(114), mpf(1)], |
| 74 | +[mpf(190**2), mpf(122**2), mpf(122*190), mpf(190), mpf(122),mpf(1)]]) |
| 75 | +B = np.array([mpf(70314326037540683861066), mpf(1467209789992686137450970), mpf(1514632596049937965560228), |
| 76 | +mpf(485439858137512552888191), mpf(112952835698501736253972), mpf(874047085530701865939630)]) |
| 77 | +X = np.array((A**-1).tolist()).dot(B) |
| 78 | +
|
| 79 | +print(X) |
| 80 | +``` |
| 81 | +We obtain these values for c[0], c[1], c[2], c[3], c[4], c[5]: |
| 82 | +[mpf('11227347570319680787') |
| 83 | + mpf('8521180195499215015') |
| 84 | + mpf('14706786521482826438') |
| 85 | + mpf('2369955372216026905') |
| 86 | + mpf('4447776531968912934') |
| 87 | + mpf('14360386757903922932')] |
| 88 | +c[0]=11227347570319680787, c[1]=8521180195499215015, c[2]=14706786521482826438, c[3]=2369955372216026905, c[4]=4447776531968912934, c[5]=14360386757903922932 |
| 89 | + |
| 90 | +Now that we know all neccesary values for c we can plug each of the numbers back into the original sagemath script with a little modification: |
| 91 | +a = 886191939093, b = 589140258545 |
| 92 | +``` |
| 93 | +import random |
| 94 | +var("x y") |
| 95 | +#flag = int(open('flag.txt','rb').read().hex(),16) |
| 96 | +#xs = [random.randint(1,256) for i in range(9)] |
| 97 | +#ys = [random.randint(1,256) for i in range(9)] |
| 98 | +#assert not any([xs[i]==ys[i] for i in range(9)]) |
| 99 | +c = [11227347570319680787, 8521180195499215015,14706786521482826438,2369955372216026905,4447776531968912934,14360386757903922932] |
| 100 | +f(x,y)=c[0]*x^2+c[1]*y^2+c[2]*x*y+c[3]*x+c[4]*y+c[5] |
| 101 | +#solns = [int(f(xs[i],ys[i])) for i in range(len(xs))] |
| 102 | +#print([(xs[i],ys[i],solns[i]) for i in range(9)]) |
| 103 | +a,b = 886191939093,589140258545 |
| 104 | +#print(a,b) |
| 105 | +print(int(f(a,b))) |
| 106 | +``` |
| 107 | +Output: 19453112380317214095677318883741141782768295 |
| 108 | +We then XOR this with 19440293474977244702108989804811578372332250 |
| 109 | +To get: 34852863801140041977112467590591656571005 |
| 110 | +We convert this to hex, then ASCII to get our flag! |
| 111 | + |
| 112 | +# Flag: |
| 113 | +flag{d8smdsx01a0} |
0 commit comments