Last active
December 13, 2015 23:19
-
-
Save rmmh/4991108 to your computer and use it in GitHub Desktop.
DCPU16 Hummingbird-2 Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SET A, plain | |
SET B, 8 | |
SET C, key | |
SET X, iv | |
JSR crypt_hummingbird2_enc | |
SET A, plain | |
SET B, 8 | |
SET C, key | |
SET X, iv | |
JSR crypt_hummingbird2_dec | |
SET A, A | |
SET PC, 0 | |
dat 0 | |
:key dat 0x2301, 0x6745, 0xAB89, 0xEFCD, 0xDCFE, 0x98BA, 0x5476, 0x1032 | |
dat 0 | |
:iv dat 0x3412, 0x7856, 0xBC9A, 0xF0DE | |
dat 0 | |
:plain dat 0x1100, 0x3322, 0x5544, 0x7766, 0x9988, 0xBBAA, 0xDDCC, 0xFFEE | |
dat 0 | |
; Hummingbird-2 Lightweight Authenticated Encryption | |
; ( http://eprint.iacr.org/2011/126.pdf ) | |
; In: A = address of message to encrypt/decrypt | |
; B = number of words to encrypt/decrypt | |
; C = address of 128-bit key | |
; X = address of 64-bit nonce | |
:crypt_hummingbird2_enc | |
SET PUSH, I | |
SET PUSH, J | |
SET PUSH, Y | |
SET PUSH, Z | |
SUB SP, 8 ; allocate 128-bit round state | |
SET Y, SP | |
ADD B, A | |
SET PUSH, B | |
SET PUSH, A | |
jsr _hum2_init | |
SET X, POP | |
:_hum2_encrypt_iter | |
SET A, [X] ; A = Plaintext Word | |
; t1 = WD16(R1 + P, K1, K2, K3, K4) | |
SET PUSH, [C+3] ; K4 | |
SET PUSH, [C+2] ; K3 | |
SET PUSH, [C+1] ; K2 | |
SET PUSH, [C] ; K1 | |
ADD A, [Y] ; R1 + P | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; t2 = WD16(R2 + t1, K5 ^ R5, K6 ^ R6, K7 ^ R7, K8 ^ R8) | |
SET I, C | |
ADD I, 7 | |
SET J, Y | |
ADD J, 8 | |
STD PUSH, [I] ; K8 ^ R8 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K7 ^ R7 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K6 ^ R6 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K5 ^ R5 | |
XOR PEEK, [J] | |
ADD A, [Y+1] ; R2 + t1 | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; t3 = WD16(R3 + t2, K1 ^ R5, K2 ^ R6, K3 ^ R7, K4 ^ R8) | |
SET I, C | |
ADD I, 3 | |
SET J, Y | |
ADD J, 8 | |
STD PUSH, [I] ; K4 ^ R8 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K3 ^ R7 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K2 ^ R6 | |
XOR PEEK, [J] | |
STD PUSH, [I] ; K1 ^ R5 | |
XOR PEEK, [J] | |
ADD A, [Y+2] ; R3 + t2 | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; C = WD16(R4 + t3, K5, K6, K7, K8) + R1 | |
SET PUSH, [C+7] ; K8 | |
SET PUSH, [C+6] ; K7 | |
SET PUSH, [C+5] ; K6 | |
SET PUSH, [C+4] ; K5 | |
ADD A, [Y+3] ; R4 + t3 | |
JSR _hum2_wd16_ABZIJ | |
ADD A, [Y] | |
SET [X], A ; write back ciphertext | |
JSR _hum2_update_AB | |
ADD X, 1 | |
IFN X, PEEK | |
SET PC, _hum2_encrypt_iter | |
SET B, POP | |
ADD SP, 8 | |
SET Z, POP | |
SET Y, POP | |
SET J, POP | |
SET I, POP | |
SET PC, POP | |
; Decryption is simply encryption in reverse | |
:crypt_hummingbird2_dec | |
SET PUSH, I | |
SET PUSH, J | |
SET PUSH, Y | |
SET PUSH, Z | |
SUB SP, 8 ; allocate 128-bit round state | |
SET Y, SP | |
ADD B, A | |
SET PUSH, B | |
SET PUSH, A | |
jsr _hum2_init | |
SET X, POP | |
:_hum2_dec_iter | |
SET A, [X] ; A = Plaintext Word | |
; enc: C = WD16(R4 + t3, K5, K6, K7, K8) + R1 | |
; dec: t3 = WD16inv(C - R1, K8, K7, K6, K5) - R4 | |
SUB A, [Y] | |
SET PUSH, [C+4] ; K5 | |
SET PUSH, [C+5] ; K6 | |
SET PUSH, [C+6] ; K7 | |
SET PUSH, [C+7] ; K8 | |
JSR _hum2_wd16inv_ABZIJ | |
SUB A, [Y+3] ; - R4 | |
SET PUSH, A ; t3 | |
; enc: t3 = WD16(R3 + t2, K1 ^ R5, K2 ^ R6, K3 ^ R7, K4 ^ R8) | |
; dec: t2 = WD16inv(t3, K4 ^ R8, K3 ^ R7, K2 ^ R6, K1 ^ R5) - R3 | |
SET I, C | |
SET J, Y | |
ADD J, 3 | |
STI PUSH, [I] ; K1 ^ R5 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K2 ^ R6 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K3 ^ R7 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K4 ^ R8 | |
XOR PEEK, [J] | |
JSR _hum2_wd16inv_ABZIJ | |
SUB A, [Y+2] ; - R3 | |
SET PUSH, A ; t2 | |
; enc: t2 = WD16(R2 + t1, K5 ^ R5, K6 ^ R6, K7 ^ R7, K8 ^ R8) | |
; dec: t1 = WD16inv(t2, K8 ^ R8, K7 ^ R7, K6 ^ R6, K5 ^ R5) - R2 | |
SET I, C | |
ADD I, 4 | |
SET J, Y | |
ADD J, 3 | |
STI PUSH, [I] ; K5 ^ R5 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K6 ^ R6 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K7 ^ R7 | |
XOR PEEK, [J] | |
STI PUSH, [I] ; K8 ^ R8 | |
XOR PEEK, [J] | |
JSR _hum2_wd16inv_ABZIJ | |
SUB A, [Y+1] ; - R2 | |
SET PUSH, A ; t1 | |
; enc: t1 = WD16(R1 + P, K1, K2, K3, K4) | |
; dec: P = WD16inv(t1, K4, K3, K2, K1) - R1 | |
SET PUSH, [C] ; K1 | |
SET PUSH, [C+1] ; K2 | |
SET PUSH, [C+2] ; K3 | |
SET PUSH, [C+3] ; K4 | |
JSR _hum2_wd16inv_ABZIJ | |
SUB A, [Y] ; - R1 | |
SET [X], A ; write back plaintext | |
; shuffle the stack around so hum2update works | |
; it expects SP+1 to be t3, and SP+3 to be t1 | |
; right now that's reversed | |
SET A, PEEK | |
SET PEEK, PICK 2 | |
SET PICK 2, A | |
JSR _hum2_update_AB | |
ADD X, 1 | |
IFN X, PEEK | |
SET PC, _hum2_dec_iter | |
SET B, POP | |
ADD SP, 8 | |
SET Z, POP | |
SET Y, POP | |
SET J, POP | |
SET I, POP | |
SET PC, POP | |
; Hummingbird2 Initialization: | |
; Clobbers ABYZIJ | |
; R(0) = (IV_1 .. IV_4; IV_1 .. IV_4) | |
:_hum2_init | |
SET I, Y | |
SET J, X | |
STI [I], [J] | |
STI [I], [J] | |
STI [I], [J] | |
STI [I], [J] | |
SUB J, 4 | |
STI [I], [J] | |
STI [I], [J] | |
STI [I], [J] | |
STI [I], [J] | |
SET X, 0 | |
:_hum2_init_iter | |
; t1 = WD16(R1 + i, K1, K2, K3, K4) | |
SET PUSH, [C+3] ; K4 | |
SET PUSH, [C+2] ; K3 | |
SET PUSH, [C+1] ; K2 | |
SET PUSH, [C] ; K1 | |
SET A, [Y] ; R1 + i | |
ADD A, X | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; t2 = WD16(R2 + t1, K5, K6, K7, K8) | |
SET PUSH, [C+7] ; K8 | |
SET PUSH, [C+6] ; K7 | |
SET PUSH, [C+5] ; K6 | |
SET PUSH, [C+4] ; K5 | |
ADD A, [Y+1] ; R2 + t1 | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; t3 = WD16(R3 + t2, K1, K2, K3, K4) | |
SET PUSH, [C+3] ; K4 | |
SET PUSH, [C+2] ; K3 | |
SET PUSH, [C+1] ; K2 | |
SET PUSH, [C] ; K1 | |
ADD A, [Y+2] ; R3 + t2 | |
JSR _hum2_wd16_ABZIJ | |
SET PUSH, A | |
; t4 = WD16(R4 + t3, K5, K6, K7, K8) | |
SET PUSH, [C+7] ; K8 | |
SET PUSH, [C+6] ; K7 | |
SET PUSH, [C+5] ; K6 | |
SET PUSH, [C+4] ; K5 | |
ADD A, [Y+3] ; R4 + t3 | |
JSR _hum2_wd16_ABZIJ | |
; update the internal state | |
; R1' = (R1 + t4) <<< 3 | |
SET I, Y | |
ADD [I], A | |
SHL [I], 3 | |
BOR [I], EX | |
; R4' = (R4 + t3) <<< 1 | |
ADD I, 3 | |
ADD [I], POP | |
SHL [I], 1 | |
BOR [I], EX | |
; R3' = (R3 + t2) <<< 8 | |
SUB I, 1 | |
ADD [I], POP | |
SHL [I], 8 | |
BOR [I], EX | |
; R2' = (R2 + t1) >>> 1 | |
SUB I, 1 | |
ADD [I], POP | |
SHR [I], 1 | |
BOR [I], EX | |
XOR [Y+4], [Y] ; R5' = R5 ^ R1' | |
XOR [Y+5], [Y+1] ; R6' = R6 ^ R2' | |
XOR [Y+6], [Y+2] ; R7' = R7 ^ R3' | |
XOR [Y+7], [Y+3] ; R8' = R8 ^ R4' | |
ADD X, 1 | |
IFN X, 4 | |
SET PC, _hum2_init_iter | |
SET PC, POP | |
; Hummingbird2 state update | |
; In: [SP+1..SP+3] = t3..t1 | |
; Out: nothing | |
:_hum2_update_AB | |
SET B, POP ; return address | |
ADD [Y], POP ; R1' = R1 + t3 | |
ADD [Y+2], POP ; R3' = R3 + t2 | |
SET A, POP ; A = t1 | |
ADD [Y+1], A ; R2' = R2 + t1 | |
ADD [Y+3], [Y] ; R4' = R4 + R1 + t3 + t1 | |
ADD [Y+3], A ; = R4 + R1' + t1 | |
XOR [Y+4], [Y] ; R5' = R5 ^ R1' | |
XOR [Y+5], [Y+1] ; R6' = R6 ^ R2' | |
XOR [Y+6], [Y+2] ; R7' = R7 ^ R3' | |
XOR [Y+7], [Y+3] ; R8' = R8 ^ R4' | |
SET PC, B | |
; WD16(x,a,b,c,d) -- keyed permutation | |
; In: A = x | |
; [SP+1..SP+4] = a..d | |
; Out: A = result | |
; | |
; Clobbers A, B, Z, I, J | |
; | |
; WD16(x,a,b,c,d) = f(f(f(f(x^a)^b)^c)^d) | |
; f(x) = L(S(x)) | |
; L(x) = x ^ (x <<< 6) ^ (x <<< 10) (<<< is left rotate) | |
; (note: here, | means binary concatenation, not bitwise or) | |
; S(x) = S12(x0 | x1) | S34(x2 | x3) | |
:_hum2_wd16_ABZIJ | |
SET Z, POP ; return address | |
; throughout, A is the current x value | |
SET I, 8 ; LOL | |
SET J, _hum2_wd16_fiter | |
:_hum2_wd16_fiter | |
XOR A, POP ; x ^ {a, b, c, d} | |
; S(x) = S12(x0 | x1) | S34(x2 | x3) | |
SHR A, 8 ; A = x0 | x1 | |
SET B, EX ; B = x2 | x3 | |
SHR B, 8 | |
SET A, [_hum2_sbox_enc + A] ; A = S12(x0 | x1) | |
SHL A, 8 | |
SET B, [_hum2_sbox_enc + B] ; B = S34(x2 | x3) | |
SHR B, 8 | |
BOR A, B | |
; L(x) = x ^ (x <<< 6) ^ (x <<< 10) | |
SET B, A | |
SHL B, 6 ; ^ (x <<< 6) | |
BOR B, EX | |
XOR A, B | |
SHL B, 4 ; ^ (x <<< 10) -- already shifted 6 | |
BOR B, EX | |
XOR A, B | |
SHR I, 1 | |
IFN I, 0 | |
SET PC, J | |
SET PC, Z ; return | |
; WD16Inv(r,d,c,b,a) = keyed inverse permutation | |
; | |
; In: A = r | |
; [SP+1..SP+4] = d..a | |
; Out: A = result | |
; | |
; Clobbers A, B, Z, I, J | |
; | |
; WD16inv(r,d,c,b,a) = f^-1(f^-1(f^-1(f^-1(r)^d)^c)^b)^a | |
; f^-1(x) = S^-1(L^-1(x)) | |
; L^-1(x) = x ^ (x <<< 2) ^ (x <<< 4) ^ (x <<< 12) ^ (x <<< 14) (<<< is left rotate) | |
; S-1(x) = S12^-1(x0 | x1) | S34^-1(x2 | x3) | |
:_hum2_wd16inv_ABZIJ | |
SET Z, POP ; return address | |
; throughout, A is the current x value | |
SET I, 8 ; LOL | |
SET J, _hum2_wd16inv_fiter | |
:_hum2_wd16inv_fiter | |
; L^-1(x) = x ^ (x <<< 2) ^ (x <<< 4) ^ (x <<< 12) ^ (x <<< 14) | |
SET B, A | |
; ^ (x <<< 2) | |
SHL B, 2 | |
BOR B, EX | |
XOR A, B | |
; ^ (x <<< 4) | |
SHL B, 2 ; 4 - 2 | |
BOR B, EX | |
XOR A, B | |
; ^ (x <<< 12) | |
SHL B, 8 ; 12 - 4 | |
BOR B, EX | |
XOR A, B | |
; ^ (x <<< 14) | |
SHL B, 2 ; 14 - 12 | |
BOR B, EX | |
XOR A, B | |
; S-1(x) = S12^-1(x0 | x1) | S34^-1(x2 | x3) | |
SHR A, 8 ; A = x0 | x1 | |
SET B, EX ; B = x2 | x3 | |
SHR B, 8 | |
SET A, [_hum2_sbox_dec + A] ; A = S12^-1(x0 | x1) | |
SHL A, 8 | |
SET B, [_hum2_sbox_dec + B] ; B = S34^-1(x2 | x3) | |
SHR B, 8 | |
BOR A, B | |
XOR A, POP ; x ^ {d, b, c, a} | |
SHR I, 1 | |
IFN I, 0 | |
SET PC, J | |
SET PC, Z ; return | |
; S(x) = S1(x0) | S2(x1) | S3(x2) | S4(x3) | |
; x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
; ----------------------------------------------------- | |
; S1(x) 7 12 14 9 2 1 5 15 11 6 13 0 4 8 10 3 | |
; S2(x) 4 10 1 6 8 15 7 12 3 0 14 13 5 9 11 2 | |
; S3(x) 2 15 12 1 5 6 10 13 14 8 3 4 0 11 9 7 | |
; S4(x) 15 4 5 8 9 7 2 1 10 3 0 14 6 12 13 11 | |
; | |
; The bytes are transposed to make the code slightly faster | |
; | |
:_hum2_sbox_enc ; S34(x0 | x1) | S12(x0 | x1) | |
dat 0x2f74,0x247a,0x2571,0x2876,0x2978,0x277f,0x2277,0x217c,0x2a73,0x2370,0x207e,0x2e7d,0x2675,0x2c79,0x2d7b,0x2b72 | |
dat 0xffc4,0xf4ca,0xf5c1,0xf8c6,0xf9c8,0xf7cf,0xf2c7,0xf1cc,0xfac3,0xf3c0,0xf0ce,0xfecd,0xf6c5,0xfcc9,0xfdcb,0xfbc2 | |
dat 0xcfe4,0xc4ea,0xc5e1,0xc8e6,0xc9e8,0xc7ef,0xc2e7,0xc1ec,0xcae3,0xc3e0,0xc0ee,0xceed,0xc6e5,0xcce9,0xcdeb,0xcbe2 | |
dat 0x1f94,0x149a,0x1591,0x1896,0x1998,0x179f,0x1297,0x119c,0x1a93,0x1390,0x109e,0x1e9d,0x1695,0x1c99,0x1d9b,0x1b92 | |
dat 0x5f24,0x542a,0x5521,0x5826,0x5928,0x572f,0x5227,0x512c,0x5a23,0x5320,0x502e,0x5e2d,0x5625,0x5c29,0x5d2b,0x5b22 | |
dat 0x6f14,0x641a,0x6511,0x6816,0x6918,0x671f,0x6217,0x611c,0x6a13,0x6310,0x601e,0x6e1d,0x6615,0x6c19,0x6d1b,0x6b12 | |
dat 0xaf54,0xa45a,0xa551,0xa856,0xa958,0xa75f,0xa257,0xa15c,0xaa53,0xa350,0xa05e,0xae5d,0xa655,0xac59,0xad5b,0xab52 | |
dat 0xdff4,0xd4fa,0xd5f1,0xd8f6,0xd9f8,0xd7ff,0xd2f7,0xd1fc,0xdaf3,0xd3f0,0xd0fe,0xdefd,0xd6f5,0xdcf9,0xddfb,0xdbf2 | |
dat 0xefb4,0xe4ba,0xe5b1,0xe8b6,0xe9b8,0xe7bf,0xe2b7,0xe1bc,0xeab3,0xe3b0,0xe0be,0xeebd,0xe6b5,0xecb9,0xedbb,0xebb2 | |
dat 0x8f64,0x846a,0x8561,0x8866,0x8968,0x876f,0x8267,0x816c,0x8a63,0x8360,0x806e,0x8e6d,0x8665,0x8c69,0x8d6b,0x8b62 | |
dat 0x3fd4,0x34da,0x35d1,0x38d6,0x39d8,0x37df,0x32d7,0x31dc,0x3ad3,0x33d0,0x30de,0x3edd,0x36d5,0x3cd9,0x3ddb,0x3bd2 | |
dat 0x4f04,0x440a,0x4501,0x4806,0x4908,0x470f,0x4207,0x410c,0x4a03,0x4300,0x400e,0x4e0d,0x4605,0x4c09,0x4d0b,0x4b02 | |
dat 0x0f44,0x044a,0x0541,0x0846,0x0948,0x074f,0x0247,0x014c,0x0a43,0x0340,0x004e,0x0e4d,0x0645,0x0c49,0x0d4b,0x0b42 | |
dat 0xbf84,0xb48a,0xb581,0xb886,0xb988,0xb78f,0xb287,0xb18c,0xba83,0xb380,0xb08e,0xbe8d,0xb685,0xbc89,0xbd8b,0xbb82 | |
dat 0x9fa4,0x94aa,0x95a1,0x98a6,0x99a8,0x97af,0x92a7,0x91ac,0x9aa3,0x93a0,0x90ae,0x9ead,0x96a5,0x9ca9,0x9dab,0x9ba2 | |
dat 0x7f34,0x743a,0x7531,0x7836,0x7938,0x773f,0x7237,0x713c,0x7a33,0x7330,0x703e,0x7e3d,0x7635,0x7c39,0x7d3b,0x7b32 | |
:_hum2_sbox_dec ; S34^-1(x0 | x1) | S12^-1(x0 | x1) | |
dat 0xcab9,0xc7b2,0xc6bf,0xc9b8,0xc1b0,0xc2bc,0xccb3,0xc5b6,0xc3b4,0xc4bd,0xc8b1,0xcfbe,0xcdb7,0xcebb,0xcbba,0xc0b5 | |
dat 0x3a59,0x3752,0x365f,0x3958,0x3150,0x325c,0x3c53,0x3556,0x3354,0x345d,0x3851,0x3f5e,0x3d57,0x3e5b,0x3b5a,0x3055 | |
dat 0x0a49,0x0742,0x064f,0x0948,0x0140,0x024c,0x0c43,0x0546,0x0344,0x044d,0x0841,0x0f4e,0x0d47,0x0e4b,0x0b4a,0x0045 | |
dat 0xaaf9,0xa7f2,0xa6ff,0xa9f8,0xa1f0,0xa2fc,0xacf3,0xa5f6,0xa3f4,0xa4fd,0xa8f1,0xaffe,0xadf7,0xaefb,0xabfa,0xa0f5 | |
dat 0xbac9,0xb7c2,0xb6cf,0xb9c8,0xb1c0,0xb2cc,0xbcc3,0xb5c6,0xb3c4,0xb4cd,0xb8c1,0xbfce,0xbdc7,0xbecb,0xbbca,0xb0c5 | |
dat 0x4a69,0x4762,0x466f,0x4968,0x4160,0x426c,0x4c63,0x4566,0x4364,0x446d,0x4861,0x4f6e,0x4d67,0x4e6b,0x4b6a,0x4065 | |
dat 0x5a99,0x5792,0x569f,0x5998,0x5190,0x529c,0x5c93,0x5596,0x5394,0x549d,0x5891,0x5f9e,0x5d97,0x5e9b,0x5b9a,0x5095 | |
dat 0xfa09,0xf702,0xf60f,0xf908,0xf100,0xf20c,0xfc03,0xf506,0xf304,0xf40d,0xf801,0xff0e,0xfd07,0xfe0b,0xfb0a,0xf005 | |
dat 0x9ad9,0x97d2,0x96df,0x99d8,0x91d0,0x92dc,0x9cd3,0x95d6,0x93d4,0x94dd,0x98d1,0x9fde,0x9dd7,0x9edb,0x9bda,0x90d5 | |
dat 0xea39,0xe732,0xe63f,0xe938,0xe130,0xe23c,0xec33,0xe536,0xe334,0xe43d,0xe831,0xef3e,0xed37,0xee3b,0xeb3a,0xe035 | |
dat 0x6ae9,0x67e2,0x66ef,0x69e8,0x61e0,0x62ec,0x6ce3,0x65e6,0x63e4,0x64ed,0x68e1,0x6fee,0x6de7,0x6eeb,0x6bea,0x60e5 | |
dat 0xda89,0xd782,0xd68f,0xd988,0xd180,0xd28c,0xdc83,0xd586,0xd384,0xd48d,0xd881,0xdf8e,0xdd87,0xde8b,0xdb8a,0xd085 | |
dat 0x2a19,0x2712,0x261f,0x2918,0x2110,0x221c,0x2c13,0x2516,0x2314,0x241d,0x2811,0x2f1e,0x2d17,0x2e1b,0x2b1a,0x2015 | |
dat 0x7aa9,0x77a2,0x76af,0x79a8,0x71a0,0x72ac,0x7ca3,0x75a6,0x73a4,0x74ad,0x78a1,0x7fae,0x7da7,0x7eab,0x7baa,0x70a5 | |
dat 0x8a29,0x8722,0x862f,0x8928,0x8120,0x822c,0x8c23,0x8526,0x8324,0x842d,0x8821,0x8f2e,0x8d27,0x8e2b,0x8b2a,0x8025 | |
dat 0x1a79,0x1772,0x167f,0x1978,0x1170,0x127c,0x1c73,0x1576,0x1374,0x147d,0x1871,0x1f7e,0x1d77,0x1e7b,0x1b7a,0x1075 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment