diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-09-10 22:12:47 -0400 |
---|---|---|
committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2017-09-10 22:12:47 -0400 |
commit | 6ceeb199181d64031f4173cfbffa066f5b9796b8 (patch) | |
tree | abda49c65817f58de5c0cb884e8848aae5723dea | |
parent | 1d82e3affd42c2336702af4a644baa8eec249ead (diff) | |
download | gen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.tar.gz gen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.tar.bz2 gen3uploader-6ceeb199181d64031f4173cfbffa066f5b9796b8.zip |
Added identifying hash to Pokémon data structure
The purpose of this hash is described in detail in pokemon.h. The hash is computed using an implementation of SHA-224. To allow the GBA sufficient time to compute this hash, a delay of 5 milliseconds was introduced on the GC side before reading a Pokémon.
-rw-r--r-- | gba/source/serialize.c | 13 | ||||
-rw-r--r-- | gba/source/sha2.c | 471 | ||||
-rw-r--r-- | gba/source/sha2.h | 74 | ||||
-rw-r--r-- | include/pokemon.h | 20 | ||||
-rw-r--r-- | source/main.c | 15 |
5 files changed, 590 insertions, 3 deletions
diff --git a/gba/source/serialize.c b/gba/source/serialize.c index c5e8570..ddd3ef2 100644 --- a/gba/source/serialize.c +++ b/gba/source/serialize.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "basestats.h" | 10 | #include "basestats.h" |
11 | #include "exptables.h" | 11 | #include "exptables.h" |
12 | #include "dexorder.h" | 12 | #include "dexorder.h" |
13 | #include "sha2.h" | ||
13 | 14 | ||
14 | u32 CalculateStat( | 15 | u32 CalculateStat( |
15 | u8 base, | 16 | u8 base, |
@@ -51,6 +52,16 @@ void PokemonIntermediateInit( | |||
51 | struct PokemonSubstruct2* sub2 = GetBoxPokemonSubstruct2(bpkm); | 52 | struct PokemonSubstruct2* sub2 = GetBoxPokemonSubstruct2(bpkm); |
52 | struct PokemonSubstruct3* sub3 = GetBoxPokemonSubstruct3(bpkm); | 53 | struct PokemonSubstruct3* sub3 = GetBoxPokemonSubstruct3(bpkm); |
53 | 54 | ||
55 | u32 identifier[3]; | ||
56 | identifier[0] = bpkm->otId; // original trainer | ||
57 | identifier[1] = bpkm->personality; // personality value | ||
58 | identifier[2] = ((const u32*)sub3)[1]; // IVs (plus two non-random bits) | ||
59 | |||
60 | sha224( | ||
61 | (const unsigned char*)identifier, | ||
62 | 12, | ||
63 | (unsigned char*)pki->key); | ||
64 | |||
54 | const struct SmallBaseStats* baseStats = BaseStatsForSpecies(sub0->species); | 65 | const struct SmallBaseStats* baseStats = BaseStatsForSpecies(sub0->species); |
55 | 66 | ||
56 | for (int i=0; i<POKEMON_NAME_LENGTH; i++) | 67 | for (int i=0; i<POKEMON_NAME_LENGTH; i++) |
@@ -63,7 +74,7 @@ void PokemonIntermediateInit( | |||
63 | pki->otName[i] = bpkm->otName[i]; | 74 | pki->otName[i] = bpkm->otName[i]; |
64 | } | 75 | } |
65 | 76 | ||
66 | pki->otId = bpkm->otId; | 77 | pki->otId = bpkm->otId & 0x0000FFFF; |
67 | pki->otGender = sub3->otGender; | 78 | pki->otGender = sub3->otGender; |
68 | pki->species = gSpeciesToNationalPokedexNum[sub0->species - 1]; | 79 | pki->species = gSpeciesToNationalPokedexNum[sub0->species - 1]; |
69 | pki->heldItem = sub0->heldItem; | 80 | pki->heldItem = sub0->heldItem; |
diff --git a/gba/source/sha2.c b/gba/source/sha2.c new file mode 100644 index 0000000..149c043 --- /dev/null +++ b/gba/source/sha2.c | |||
@@ -0,0 +1,471 @@ | |||
1 | /* | ||
2 | * FIPS 180-2 SHA-224/256/384/512 implementation | ||
3 | * Last update: 02/02/2007 | ||
4 | * Issue date: 04/30/2005 | ||
5 | * | ||
6 | * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of the project nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #if 0 | ||
35 | #define UNROLL_LOOPS /* Enable loops unrolling */ | ||
36 | #endif | ||
37 | |||
38 | #include <string.h> | ||
39 | |||
40 | #include "sha2.h" | ||
41 | |||
42 | #define SHFR(x, n) (x >> n) | ||
43 | #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) | ||
44 | #define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) | ||
45 | #define CH(x, y, z) ((x & y) ^ (~x & z)) | ||
46 | #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | ||
47 | |||
48 | #define SHA256_F1(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) | ||
49 | #define SHA256_F2(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) | ||
50 | #define SHA256_F3(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHFR(x, 3)) | ||
51 | #define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10)) | ||
52 | |||
53 | #define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) | ||
54 | #define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) | ||
55 | #define SHA512_F3(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHFR(x, 7)) | ||
56 | #define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x, 6)) | ||
57 | |||
58 | #define UNPACK32(x, str) \ | ||
59 | { \ | ||
60 | *((str) + 3) = (uint8) ((x) ); \ | ||
61 | *((str) + 2) = (uint8) ((x) >> 8); \ | ||
62 | *((str) + 1) = (uint8) ((x) >> 16); \ | ||
63 | *((str) + 0) = (uint8) ((x) >> 24); \ | ||
64 | } | ||
65 | |||
66 | #define PACK32(str, x) \ | ||
67 | { \ | ||
68 | *(x) = ((uint32) *((str) + 3) ) \ | ||
69 | | ((uint32) *((str) + 2) << 8) \ | ||
70 | | ((uint32) *((str) + 1) << 16) \ | ||
71 | | ((uint32) *((str) + 0) << 24); \ | ||
72 | } | ||
73 | |||
74 | #define UNPACK64(x, str) \ | ||
75 | { \ | ||
76 | *((str) + 7) = (uint8) ((x) ); \ | ||
77 | *((str) + 6) = (uint8) ((x) >> 8); \ | ||
78 | *((str) + 5) = (uint8) ((x) >> 16); \ | ||
79 | *((str) + 4) = (uint8) ((x) >> 24); \ | ||
80 | *((str) + 3) = (uint8) ((x) >> 32); \ | ||
81 | *((str) + 2) = (uint8) ((x) >> 40); \ | ||
82 | *((str) + 1) = (uint8) ((x) >> 48); \ | ||
83 | *((str) + 0) = (uint8) ((x) >> 56); \ | ||
84 | } | ||
85 | |||
86 | #define PACK64(str, x) \ | ||
87 | { \ | ||
88 | *(x) = ((uint64) *((str) + 7) ) \ | ||
89 | | ((uint64) *((str) + 6) << 8) \ | ||
90 | | ((uint64) *((str) + 5) << 16) \ | ||
91 | | ((uint64) *((str) + 4) << 24) \ | ||
92 | | ((uint64) *((str) + 3) << 32) \ | ||
93 | | ((uint64) *((str) + 2) << 40) \ | ||
94 | | ((uint64) *((str) + 1) << 48) \ | ||
95 | | ((uint64) *((str) + 0) << 56); \ | ||
96 | } | ||
97 | |||
98 | /* Macros used for loops unrolling */ | ||
99 | |||
100 | #define SHA256_SCR(i) \ | ||
101 | { \ | ||
102 | w[i] = SHA256_F4(w[i - 2]) + w[i - 7] \ | ||
103 | + SHA256_F3(w[i - 15]) + w[i - 16]; \ | ||
104 | } | ||
105 | |||
106 | #define SHA512_SCR(i) \ | ||
107 | { \ | ||
108 | w[i] = SHA512_F4(w[i - 2]) + w[i - 7] \ | ||
109 | + SHA512_F3(w[i - 15]) + w[i - 16]; \ | ||
110 | } | ||
111 | |||
112 | #define SHA256_EXP(a, b, c, d, e, f, g, h, j) \ | ||
113 | { \ | ||
114 | t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ | ||
115 | + sha256_k[j] + w[j]; \ | ||
116 | t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ | ||
117 | wv[d] += t1; \ | ||
118 | wv[h] = t1 + t2; \ | ||
119 | } | ||
120 | |||
121 | #define SHA512_EXP(a, b, c, d, e, f, g ,h, j) \ | ||
122 | { \ | ||
123 | t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) \ | ||
124 | + sha512_k[j] + w[j]; \ | ||
125 | t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]); \ | ||
126 | wv[d] += t1; \ | ||
127 | wv[h] = t1 + t2; \ | ||
128 | } | ||
129 | |||
130 | uint32 sha224_h0[8] = | ||
131 | {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, | ||
132 | 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; | ||
133 | |||
134 | uint32 sha256_h0[8] = | ||
135 | {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, | ||
136 | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; | ||
137 | |||
138 | uint32 sha256_k[64] = | ||
139 | {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | ||
140 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | ||
141 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | ||
142 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | ||
143 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | ||
144 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | ||
145 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | ||
146 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | ||
147 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | ||
148 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | ||
149 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | ||
150 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | ||
151 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | ||
152 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | ||
153 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | ||
154 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; | ||
155 | |||
156 | /* SHA-256 functions */ | ||
157 | |||
158 | void sha256_transf(sha256_ctx *ctx, const unsigned char *message, | ||
159 | unsigned int block_nb) | ||
160 | { | ||
161 | uint32 w[64]; | ||
162 | uint32 wv[8]; | ||
163 | uint32 t1, t2; | ||
164 | const unsigned char *sub_block; | ||
165 | int i; | ||
166 | |||
167 | #ifndef UNROLL_LOOPS | ||
168 | int j; | ||
169 | #endif | ||
170 | |||
171 | for (i = 0; i < (int) block_nb; i++) { | ||
172 | sub_block = message + (i << 6); | ||
173 | |||
174 | #ifndef UNROLL_LOOPS | ||
175 | for (j = 0; j < 16; j++) { | ||
176 | PACK32(&sub_block[j << 2], &w[j]); | ||
177 | } | ||
178 | |||
179 | for (j = 16; j < 64; j++) { | ||
180 | SHA256_SCR(j); | ||
181 | } | ||
182 | |||
183 | for (j = 0; j < 8; j++) { | ||
184 | wv[j] = ctx->h[j]; | ||
185 | } | ||
186 | |||
187 | for (j = 0; j < 64; j++) { | ||
188 | t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6]) | ||
189 | + sha256_k[j] + w[j]; | ||
190 | t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]); | ||
191 | wv[7] = wv[6]; | ||
192 | wv[6] = wv[5]; | ||
193 | wv[5] = wv[4]; | ||
194 | wv[4] = wv[3] + t1; | ||
195 | wv[3] = wv[2]; | ||
196 | wv[2] = wv[1]; | ||
197 | wv[1] = wv[0]; | ||
198 | wv[0] = t1 + t2; | ||
199 | } | ||
200 | |||
201 | for (j = 0; j < 8; j++) { | ||
202 | ctx->h[j] += wv[j]; | ||
203 | } | ||
204 | #else | ||
205 | PACK32(&sub_block[ 0], &w[ 0]); PACK32(&sub_block[ 4], &w[ 1]); | ||
206 | PACK32(&sub_block[ 8], &w[ 2]); PACK32(&sub_block[12], &w[ 3]); | ||
207 | PACK32(&sub_block[16], &w[ 4]); PACK32(&sub_block[20], &w[ 5]); | ||
208 | PACK32(&sub_block[24], &w[ 6]); PACK32(&sub_block[28], &w[ 7]); | ||
209 | PACK32(&sub_block[32], &w[ 8]); PACK32(&sub_block[36], &w[ 9]); | ||
210 | PACK32(&sub_block[40], &w[10]); PACK32(&sub_block[44], &w[11]); | ||
211 | PACK32(&sub_block[48], &w[12]); PACK32(&sub_block[52], &w[13]); | ||
212 | PACK32(&sub_block[56], &w[14]); PACK32(&sub_block[60], &w[15]); | ||
213 | |||
214 | SHA256_SCR(16); SHA256_SCR(17); SHA256_SCR(18); SHA256_SCR(19); | ||
215 | SHA256_SCR(20); SHA256_SCR(21); SHA256_SCR(22); SHA256_SCR(23); | ||
216 | SHA256_SCR(24); SHA256_SCR(25); SHA256_SCR(26); SHA256_SCR(27); | ||
217 | SHA256_SCR(28); SHA256_SCR(29); SHA256_SCR(30); SHA256_SCR(31); | ||
218 | SHA256_SCR(32); SHA256_SCR(33); SHA256_SCR(34); SHA256_SCR(35); | ||
219 | SHA256_SCR(36); SHA256_SCR(37); SHA256_SCR(38); SHA256_SCR(39); | ||
220 | SHA256_SCR(40); SHA256_SCR(41); SHA256_SCR(42); SHA256_SCR(43); | ||
221 | SHA256_SCR(44); SHA256_SCR(45); SHA256_SCR(46); SHA256_SCR(47); | ||
222 | SHA256_SCR(48); SHA256_SCR(49); SHA256_SCR(50); SHA256_SCR(51); | ||
223 | SHA256_SCR(52); SHA256_SCR(53); SHA256_SCR(54); SHA256_SCR(55); | ||
224 | SHA256_SCR(56); SHA256_SCR(57); SHA256_SCR(58); SHA256_SCR(59); | ||
225 | SHA256_SCR(60); SHA256_SCR(61); SHA256_SCR(62); SHA256_SCR(63); | ||
226 | |||
227 | wv[0] = ctx->h[0]; wv[1] = ctx->h[1]; | ||
228 | wv[2] = ctx->h[2]; wv[3] = ctx->h[3]; | ||
229 | wv[4] = ctx->h[4]; wv[5] = ctx->h[5]; | ||
230 | wv[6] = ctx->h[6]; wv[7] = ctx->h[7]; | ||
231 | |||
232 | SHA256_EXP(0,1,2,3,4,5,6,7, 0); SHA256_EXP(7,0,1,2,3,4,5,6, 1); | ||
233 | SHA256_EXP(6,7,0,1,2,3,4,5, 2); SHA256_EXP(5,6,7,0,1,2,3,4, 3); | ||
234 | SHA256_EXP(4,5,6,7,0,1,2,3, 4); SHA256_EXP(3,4,5,6,7,0,1,2, 5); | ||
235 | SHA256_EXP(2,3,4,5,6,7,0,1, 6); SHA256_EXP(1,2,3,4,5,6,7,0, 7); | ||
236 | SHA256_EXP(0,1,2,3,4,5,6,7, 8); SHA256_EXP(7,0,1,2,3,4,5,6, 9); | ||
237 | SHA256_EXP(6,7,0,1,2,3,4,5,10); SHA256_EXP(5,6,7,0,1,2,3,4,11); | ||
238 | SHA256_EXP(4,5,6,7,0,1,2,3,12); SHA256_EXP(3,4,5,6,7,0,1,2,13); | ||
239 | SHA256_EXP(2,3,4,5,6,7,0,1,14); SHA256_EXP(1,2,3,4,5,6,7,0,15); | ||
240 | SHA256_EXP(0,1,2,3,4,5,6,7,16); SHA256_EXP(7,0,1,2,3,4,5,6,17); | ||
241 | SHA256_EXP(6,7,0,1,2,3,4,5,18); SHA256_EXP(5,6,7,0,1,2,3,4,19); | ||
242 | SHA256_EXP(4,5,6,7,0,1,2,3,20); SHA256_EXP(3,4,5,6,7,0,1,2,21); | ||
243 | SHA256_EXP(2,3,4,5,6,7,0,1,22); SHA256_EXP(1,2,3,4,5,6,7,0,23); | ||
244 | SHA256_EXP(0,1,2,3,4,5,6,7,24); SHA256_EXP(7,0,1,2,3,4,5,6,25); | ||
245 | SHA256_EXP(6,7,0,1,2,3,4,5,26); SHA256_EXP(5,6,7,0,1,2,3,4,27); | ||
246 | SHA256_EXP(4,5,6,7,0,1,2,3,28); SHA256_EXP(3,4,5,6,7,0,1,2,29); | ||
247 | SHA256_EXP(2,3,4,5,6,7,0,1,30); SHA256_EXP(1,2,3,4,5,6,7,0,31); | ||
248 | SHA256_EXP(0,1,2,3,4,5,6,7,32); SHA256_EXP(7,0,1,2,3,4,5,6,33); | ||
249 | SHA256_EXP(6,7,0,1,2,3,4,5,34); SHA256_EXP(5,6,7,0,1,2,3,4,35); | ||
250 | SHA256_EXP(4,5,6,7,0,1,2,3,36); SHA256_EXP(3,4,5,6,7,0,1,2,37); | ||
251 | SHA256_EXP(2,3,4,5,6,7,0,1,38); SHA256_EXP(1,2,3,4,5,6,7,0,39); | ||
252 | SHA256_EXP(0,1,2,3,4,5,6,7,40); SHA256_EXP(7,0,1,2,3,4,5,6,41); | ||
253 | SHA256_EXP(6,7,0,1,2,3,4,5,42); SHA256_EXP(5,6,7,0,1,2,3,4,43); | ||
254 | SHA256_EXP(4,5,6,7,0,1,2,3,44); SHA256_EXP(3,4,5,6,7,0,1,2,45); | ||
255 | SHA256_EXP(2,3,4,5,6,7,0,1,46); SHA256_EXP(1,2,3,4,5,6,7,0,47); | ||
256 | SHA256_EXP(0,1,2,3,4,5,6,7,48); SHA256_EXP(7,0,1,2,3,4,5,6,49); | ||
257 | SHA256_EXP(6,7,0,1,2,3,4,5,50); SHA256_EXP(5,6,7,0,1,2,3,4,51); | ||
258 | SHA256_EXP(4,5,6,7,0,1,2,3,52); SHA256_EXP(3,4,5,6,7,0,1,2,53); | ||
259 | SHA256_EXP(2,3,4,5,6,7,0,1,54); SHA256_EXP(1,2,3,4,5,6,7,0,55); | ||
260 | SHA256_EXP(0,1,2,3,4,5,6,7,56); SHA256_EXP(7,0,1,2,3,4,5,6,57); | ||
261 | SHA256_EXP(6,7,0,1,2,3,4,5,58); SHA256_EXP(5,6,7,0,1,2,3,4,59); | ||
262 | SHA256_EXP(4,5,6,7,0,1,2,3,60); SHA256_EXP(3,4,5,6,7,0,1,2,61); | ||
263 | SHA256_EXP(2,3,4,5,6,7,0,1,62); SHA256_EXP(1,2,3,4,5,6,7,0,63); | ||
264 | |||
265 | ctx->h[0] += wv[0]; ctx->h[1] += wv[1]; | ||
266 | ctx->h[2] += wv[2]; ctx->h[3] += wv[3]; | ||
267 | ctx->h[4] += wv[4]; ctx->h[5] += wv[5]; | ||
268 | ctx->h[6] += wv[6]; ctx->h[7] += wv[7]; | ||
269 | #endif /* !UNROLL_LOOPS */ | ||
270 | } | ||
271 | } | ||
272 | |||
273 | void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) | ||
274 | { | ||
275 | sha256_ctx ctx; | ||
276 | |||
277 | sha256_init(&ctx); | ||
278 | sha256_update(&ctx, message, len); | ||
279 | sha256_final(&ctx, digest); | ||
280 | } | ||
281 | |||
282 | void sha256_init(sha256_ctx *ctx) | ||
283 | { | ||
284 | #ifndef UNROLL_LOOPS | ||
285 | int i; | ||
286 | for (i = 0; i < 8; i++) { | ||
287 | ctx->h[i] = sha256_h0[i]; | ||
288 | } | ||
289 | #else | ||
290 | ctx->h[0] = sha256_h0[0]; ctx->h[1] = sha256_h0[1]; | ||
291 | ctx->h[2] = sha256_h0[2]; ctx->h[3] = sha256_h0[3]; | ||
292 | ctx->h[4] = sha256_h0[4]; ctx->h[5] = sha256_h0[5]; | ||
293 | ctx->h[6] = sha256_h0[6]; ctx->h[7] = sha256_h0[7]; | ||
294 | #endif /* !UNROLL_LOOPS */ | ||
295 | |||
296 | ctx->len = 0; | ||
297 | ctx->tot_len = 0; | ||
298 | } | ||
299 | |||
300 | void sha256_update(sha256_ctx *ctx, const unsigned char *message, | ||
301 | unsigned int len) | ||
302 | { | ||
303 | unsigned int block_nb; | ||
304 | unsigned int new_len, rem_len, tmp_len; | ||
305 | const unsigned char *shifted_message; | ||
306 | |||
307 | tmp_len = SHA256_BLOCK_SIZE - ctx->len; | ||
308 | rem_len = len < tmp_len ? len : tmp_len; | ||
309 | |||
310 | memcpy(&ctx->block[ctx->len], message, rem_len); | ||
311 | |||
312 | if (ctx->len + len < SHA256_BLOCK_SIZE) { | ||
313 | ctx->len += len; | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | new_len = len - rem_len; | ||
318 | block_nb = new_len / SHA256_BLOCK_SIZE; | ||
319 | |||
320 | shifted_message = message + rem_len; | ||
321 | |||
322 | sha256_transf(ctx, ctx->block, 1); | ||
323 | sha256_transf(ctx, shifted_message, block_nb); | ||
324 | |||
325 | rem_len = new_len % SHA256_BLOCK_SIZE; | ||
326 | |||
327 | memcpy(ctx->block, &shifted_message[block_nb << 6], | ||
328 | rem_len); | ||
329 | |||
330 | ctx->len = rem_len; | ||
331 | ctx->tot_len += (block_nb + 1) << 6; | ||
332 | } | ||
333 | |||
334 | void sha256_final(sha256_ctx *ctx, unsigned char *digest) | ||
335 | { | ||
336 | unsigned int block_nb; | ||
337 | unsigned int pm_len; | ||
338 | unsigned int len_b; | ||
339 | |||
340 | #ifndef UNROLL_LOOPS | ||
341 | int i; | ||
342 | #endif | ||
343 | |||
344 | block_nb = (1 + ((SHA256_BLOCK_SIZE - 9) | ||
345 | < (ctx->len % SHA256_BLOCK_SIZE))); | ||
346 | |||
347 | len_b = (ctx->tot_len + ctx->len) << 3; | ||
348 | pm_len = block_nb << 6; | ||
349 | |||
350 | memset(ctx->block + ctx->len, 0, pm_len - ctx->len); | ||
351 | ctx->block[ctx->len] = 0x80; | ||
352 | UNPACK32(len_b, ctx->block + pm_len - 4); | ||
353 | |||
354 | sha256_transf(ctx, ctx->block, block_nb); | ||
355 | |||
356 | #ifndef UNROLL_LOOPS | ||
357 | for (i = 0 ; i < 8; i++) { | ||
358 | UNPACK32(ctx->h[i], &digest[i << 2]); | ||
359 | } | ||
360 | #else | ||
361 | UNPACK32(ctx->h[0], &digest[ 0]); | ||
362 | UNPACK32(ctx->h[1], &digest[ 4]); | ||
363 | UNPACK32(ctx->h[2], &digest[ 8]); | ||
364 | UNPACK32(ctx->h[3], &digest[12]); | ||
365 | UNPACK32(ctx->h[4], &digest[16]); | ||
366 | UNPACK32(ctx->h[5], &digest[20]); | ||
367 | UNPACK32(ctx->h[6], &digest[24]); | ||
368 | UNPACK32(ctx->h[7], &digest[28]); | ||
369 | #endif /* !UNROLL_LOOPS */ | ||
370 | } | ||
371 | |||
372 | /* SHA-224 functions */ | ||
373 | |||
374 | void sha224(const unsigned char *message, unsigned int len, | ||
375 | unsigned char *digest) | ||
376 | { | ||
377 | sha224_ctx ctx; | ||
378 | |||
379 | sha224_init(&ctx); | ||
380 | sha224_update(&ctx, message, len); | ||
381 | sha224_final(&ctx, digest); | ||
382 | } | ||
383 | |||
384 | void sha224_init(sha224_ctx *ctx) | ||
385 | { | ||
386 | #ifndef UNROLL_LOOPS | ||
387 | int i; | ||
388 | for (i = 0; i < 8; i++) { | ||
389 | ctx->h[i] = sha224_h0[i]; | ||
390 | } | ||
391 | #else | ||
392 | ctx->h[0] = sha224_h0[0]; ctx->h[1] = sha224_h0[1]; | ||
393 | ctx->h[2] = sha224_h0[2]; ctx->h[3] = sha224_h0[3]; | ||
394 | ctx->h[4] = sha224_h0[4]; ctx->h[5] = sha224_h0[5]; | ||
395 | ctx->h[6] = sha224_h0[6]; ctx->h[7] = sha224_h0[7]; | ||
396 | #endif /* !UNROLL_LOOPS */ | ||
397 | |||
398 | ctx->len = 0; | ||
399 | ctx->tot_len = 0; | ||
400 | } | ||
401 | |||
402 | void sha224_update(sha224_ctx *ctx, const unsigned char *message, | ||
403 | unsigned int len) | ||
404 | { | ||
405 | unsigned int block_nb; | ||
406 | unsigned int new_len, rem_len, tmp_len; | ||
407 | const unsigned char *shifted_message; | ||
408 | |||
409 | tmp_len = SHA224_BLOCK_SIZE - ctx->len; | ||
410 | rem_len = len < tmp_len ? len : tmp_len; | ||
411 | |||
412 | memcpy(&ctx->block[ctx->len], message, rem_len); | ||
413 | |||
414 | if (ctx->len + len < SHA224_BLOCK_SIZE) { | ||
415 | ctx->len += len; | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | new_len = len - rem_len; | ||
420 | block_nb = new_len / SHA224_BLOCK_SIZE; | ||
421 | |||
422 | shifted_message = message + rem_len; | ||
423 | |||
424 | sha256_transf(ctx, ctx->block, 1); | ||
425 | sha256_transf(ctx, shifted_message, block_nb); | ||
426 | |||
427 | rem_len = new_len % SHA224_BLOCK_SIZE; | ||
428 | |||
429 | memcpy(ctx->block, &shifted_message[block_nb << 6], | ||
430 | rem_len); | ||
431 | |||
432 | ctx->len = rem_len; | ||
433 | ctx->tot_len += (block_nb + 1) << 6; | ||
434 | } | ||
435 | |||
436 | void sha224_final(sha224_ctx *ctx, unsigned char *digest) | ||
437 | { | ||
438 | unsigned int block_nb; | ||
439 | unsigned int pm_len; | ||
440 | unsigned int len_b; | ||
441 | |||
442 | #ifndef UNROLL_LOOPS | ||
443 | int i; | ||
444 | #endif | ||
445 | |||
446 | block_nb = (1 + ((SHA224_BLOCK_SIZE - 9) | ||
447 | < (ctx->len % SHA224_BLOCK_SIZE))); | ||
448 | |||
449 | len_b = (ctx->tot_len + ctx->len) << 3; | ||
450 | pm_len = block_nb << 6; | ||
451 | |||
452 | memset(ctx->block + ctx->len, 0, pm_len - ctx->len); | ||
453 | ctx->block[ctx->len] = 0x80; | ||
454 | UNPACK32(len_b, ctx->block + pm_len - 4); | ||
455 | |||
456 | sha256_transf(ctx, ctx->block, block_nb); | ||
457 | |||
458 | #ifndef UNROLL_LOOPS | ||
459 | for (i = 0 ; i < 7; i++) { | ||
460 | UNPACK32(ctx->h[i], &digest[i << 2]); | ||
461 | } | ||
462 | #else | ||
463 | UNPACK32(ctx->h[0], &digest[ 0]); | ||
464 | UNPACK32(ctx->h[1], &digest[ 4]); | ||
465 | UNPACK32(ctx->h[2], &digest[ 8]); | ||
466 | UNPACK32(ctx->h[3], &digest[12]); | ||
467 | UNPACK32(ctx->h[4], &digest[16]); | ||
468 | UNPACK32(ctx->h[5], &digest[20]); | ||
469 | UNPACK32(ctx->h[6], &digest[24]); | ||
470 | #endif /* !UNROLL_LOOPS */ | ||
471 | } | ||
diff --git a/gba/source/sha2.h b/gba/source/sha2.h new file mode 100644 index 0000000..efd3059 --- /dev/null +++ b/gba/source/sha2.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * FIPS 180-2 SHA-224/256/384/512 implementation | ||
3 | * Last update: 02/02/2007 | ||
4 | * Issue date: 04/30/2005 | ||
5 | * | ||
6 | * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch> | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of the project nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | ||
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #ifndef SHA2_H | ||
35 | #define SHA2_H | ||
36 | |||
37 | #define SHA224_DIGEST_SIZE ( 224 / 8) | ||
38 | #define SHA256_DIGEST_SIZE ( 256 / 8) | ||
39 | |||
40 | #define SHA256_BLOCK_SIZE ( 512 / 8) | ||
41 | #define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE | ||
42 | |||
43 | #ifndef SHA2_TYPES | ||
44 | #define SHA2_TYPES | ||
45 | typedef unsigned char uint8; | ||
46 | typedef unsigned int uint32; | ||
47 | typedef unsigned long long uint64; | ||
48 | #endif | ||
49 | |||
50 | typedef struct { | ||
51 | unsigned int tot_len; | ||
52 | unsigned int len; | ||
53 | unsigned char block[2 * SHA256_BLOCK_SIZE]; | ||
54 | uint32 h[8]; | ||
55 | } sha256_ctx; | ||
56 | |||
57 | typedef sha256_ctx sha224_ctx; | ||
58 | |||
59 | void sha224_init(sha224_ctx *ctx); | ||
60 | void sha224_update(sha224_ctx *ctx, const unsigned char *message, | ||
61 | unsigned int len); | ||
62 | void sha224_final(sha224_ctx *ctx, unsigned char *digest); | ||
63 | void sha224(const unsigned char *message, unsigned int len, | ||
64 | unsigned char *digest); | ||
65 | |||
66 | void sha256_init(sha256_ctx * ctx); | ||
67 | void sha256_update(sha256_ctx *ctx, const unsigned char *message, | ||
68 | unsigned int len); | ||
69 | void sha256_final(sha256_ctx *ctx, unsigned char *digest); | ||
70 | void sha256(const unsigned char *message, unsigned int len, | ||
71 | unsigned char *digest); | ||
72 | |||
73 | #endif /* !SHA2_H */ | ||
74 | |||
diff --git a/include/pokemon.h b/include/pokemon.h index d8a7265..bd311c4 100644 --- a/include/pokemon.h +++ b/include/pokemon.h | |||
@@ -20,8 +20,23 @@ enum PokemonLanguage { | |||
20 | Spanish = 7 | 20 | Spanish = 7 |
21 | }; | 21 | }; |
22 | 22 | ||
23 | struct PokemonIntermediate { | 23 | struct __attribute__((aligned(4))) PokemonIntermediate { |
24 | u32 otId; | 24 | // a hash that can be used to identify the Pokémon. because the games do not |
25 | // naturally generate unique identifiers for Pokémon, this hash is generated | ||
26 | // from parts of the Pokémon's data that are guaranteed never to change. the | ||
27 | // parts used are the trainer ID and secret ID of the Pokémon's original | ||
28 | // trainer, the personality value, and the IVs. almost all of this data is | ||
29 | // secret, and should not be derivable from the identifier, which is why the | ||
30 | // identifier is hashed. while this identifier is not guaranteed to be unique, | ||
31 | // probability of collision is astronomically small given that the | ||
32 | // personality value and IVs provide essentially 52 bits of randomness | ||
33 | // (technically less because the IVs of bred Pokémon are not uniformly | ||
34 | // random, but this variation is statistically insignificant). the OT ID, | ||
35 | // while not uniformly random (amongst Pokémon), is included as a sort of | ||
36 | // "namespace", in that any Pokémon with matching PVs and IVs must also have | ||
37 | // the same OT, thus preventing collaboratively finding PV and IV collisions. | ||
38 | u32 key[7]; | ||
39 | |||
25 | u32 experience; | 40 | u32 experience; |
26 | 41 | ||
27 | // the stats are calculated from the base stats, IVs, EVs, and Nature, before | 42 | // the stats are calculated from the base stats, IVs, EVs, and Nature, before |
@@ -36,6 +51,7 @@ struct PokemonIntermediate { | |||
36 | u16 species; | 51 | u16 species; |
37 | u16 heldItem; | 52 | u16 heldItem; |
38 | u16 moves[4]; | 53 | u16 moves[4]; |
54 | u16 otId; // only the lower 2 bytes, because the upper 2 are secret | ||
39 | 55 | ||
40 | u8 ppBonuses; | 56 | u8 ppBonuses; |
41 | u8 otGender:1; | 57 | u8 otGender:1; |
diff --git a/source/main.c b/source/main.c index 1355533..3806106 100644 --- a/source/main.c +++ b/source/main.c | |||
@@ -210,6 +210,8 @@ void* extractor(void* userdata) | |||
210 | 210 | ||
211 | for (u32 i = 0; i < partyCount; i++) | 211 | for (u32 i = 0; i < partyCount; i++) |
212 | { | 212 | { |
213 | usleep(5000); | ||
214 | |||
213 | u32 rawdata[sizeof(struct PokemonIntermediate) / 4]; | 215 | u32 rawdata[sizeof(struct PokemonIntermediate) / 4]; |
214 | getMsgArr(rawdata, sizeof(struct PokemonIntermediate) / 4); | 216 | getMsgArr(rawdata, sizeof(struct PokemonIntermediate) / 4); |
215 | 217 | ||
@@ -221,6 +223,18 @@ void* extractor(void* userdata) | |||
221 | char d_otName[22]; | 223 | char d_otName[22]; |
222 | decodePokemonCharset(pki->otName, 7, d_otName, pki->language); | 224 | decodePokemonCharset(pki->otName, 7, d_otName, pki->language); |
223 | 225 | ||
226 | char d_key[57]; | ||
227 | sprintf( | ||
228 | d_key, | ||
229 | "%08lx%08lx%08lx%08lx%08lx%08lx%08lx", | ||
230 | pki->key[0], | ||
231 | pki->key[1], | ||
232 | pki->key[2], | ||
233 | pki->key[3], | ||
234 | pki->key[4], | ||
235 | pki->key[5], | ||
236 | pki->key[6]); | ||
237 | |||
224 | printf("Species: %d\n", __builtin_bswap16(pki->species)); | 238 | printf("Species: %d\n", __builtin_bswap16(pki->species)); |
225 | printf("Nickname: %s\n", d_pokename); | 239 | printf("Nickname: %s\n", d_pokename); |
226 | printf("OT: %s\n", d_otName); | 240 | printf("OT: %s\n", d_otName); |
@@ -231,6 +245,7 @@ void* extractor(void* userdata) | |||
231 | printf("Special Attack: %ld\n", __builtin_bswap32(pki->spAttack)); | 245 | printf("Special Attack: %ld\n", __builtin_bswap32(pki->spAttack)); |
232 | printf("Special Defense: %ld\n", __builtin_bswap32(pki->spDefense)); | 246 | printf("Special Defense: %ld\n", __builtin_bswap32(pki->spDefense)); |
233 | printf("Speed: %ld\n", __builtin_bswap32(pki->speed)); | 247 | printf("Speed: %ld\n", __builtin_bswap32(pki->speed)); |
248 | printf("Key: %s\n", d_key); | ||
234 | 249 | ||
235 | printf("\n"); | 250 | printf("\n"); |
236 | } | 251 | } |