[Android Q&A, Help & Troubleshooting] leeyiyuan:
It is too difficult

I extracted the save files from my device and indeed, there was a 256 bit checksum appended at the end of the files. I digged a bit, and found (using IDA) the checksum in libgof2hdaa.so, located in data > app-lib > net.fishlabs.gof2hdallandroid2012-1. The assembly code for the checksum function is presented below.

.text:001529A4 ; =============== S U B R O U T I N E =======================================
.text:001529A4
.text:001529A4
.text:001529A4 ; RecordHandler::addHash(int)
.text:001529A4 EXPORT _ZN13RecordHandler7addHashEi
.text:001529A4 _ZN13RecordHandler7addHashEi ; CODE XREF: RecordHandler::recordStoreWrite(int)+1002p
.text:001529A4 ; RecordHandler::changeSaveDirectoryToBackupDirectory(void)+150p ...
.text:001529A4
.text:001529A4 var_60 = -0x60
.text:001529A4 var_58 = -0x58
.text:001529A4 var_54 = -0x54
.text:001529A4 src = -0x4C
.text:001529A4 var_48 = -0x48
.text:001529A4 var_2C = -0x2C
.text:001529A4
.text:001529A4 PUSH {R4-R7,LR}
.text:001529A6 MOV R7, R11
.text:001529A8 MOV R6, R10
.text:001529AA MOV R5, R9
.text:001529AC MOV R4, R8
.text:001529AE PUSH {R4-R7}
.text:001529B0 LDR R4, =(__stack_chk_guard_ptr - 0x1529BA)
.text:001529B2 SUB SP, SP, #0x3C
.text:001529B4 MOV R10, R0
.text:001529B6 ADD R4, PC
.text:001529B8 LDR R4, [R4]
.text:001529BA MOVS R0, #0
.text:001529BC MOV R11, R1
.text:001529BE LDR R3, [R4]
.text:001529C0 STR R0, [SP,#0x60+src]
.text:001529C2 MOV R9, R0
.text:001529C4 STR R3, [SP,#0x60+var_2C]
.text:001529C6 MOV R0, R10
.text:001529C8 ADD R1, SP, #0x60+src
.text:001529CA MOV R2, R11
.text:001529CC MOVS R3, #0
.text:001529CE BL _ZN13RecordHandler21readRecordAsByteArrayEPPaib ; RecordHandler::readRecordAsByteArray(signed char **,int,bool)
.text:001529D2 SUBS R6, R0, #0
.text:001529D4 BLT loc_152A8E
.text:001529D6 MOVS R0, #0x20
.text:001529D8 BLX _Znaj ; operator new[](uint)
.text:001529DC MOV R8, R0
.text:001529DE MOVS R0, #0x70
.text:001529E0 BLX _Znwj ; operator new(uint)
.text:001529E4 MOVS R5, R0
[COLOR="red"].text:001529E6 BLX SHA256_Init[/COLOR]
.text:001529EA LDR R1, [SP,#0x60+src]
.text:001529EC MOVS R2, R6
.text:001529EE MOVS R0, R5
[COLOR="red"].text:001529F0 BLX SHA256_Update[/COLOR]
.text:001529F4 LDR R2, =(aZr0ll3r0aster_ - 0x152A00)
.text:001529F6 ADD R1, SP, #0x60+var_48
.text:001529F8 STR R1, [SP,#0x60+var_54]
.text:001529FA MOV R12, R2
.text:001529FC ADD R12, PC ; "#+-ºR0LL3r(0aSter&_%=$+#"
.text:001529FE MOV R3, R12
.text:00152A00 LDMIA R3!, {R0,R2,R7}
.text:00152A02 STMIA R1!, {R0,R2,R7}
.text:00152A04 STR R1, [SP,#0x60+var_58]
.text:00152A06 LDMIA R3!, {R0,R2,R7}
.text:00152A08 STMIA R1!, {R0,R2,R7}
.text:00152A0A LDRB R2, [R3]
.text:00152A0C MOVS R0, R5
.text:00152A0E MOVS R7, R6
.text:00152A10 STRB R2, [R1]
.text:00152A12 ADD R1, SP, #0x60+var_48
.text:00152A14 MOVS R2, #0x19
[COLOR="Red"].text:00152A16 BLX SHA256_Update[/COLOR]
.text:00152A1A LDR R3, =(g_android_origami_super_club_ptr - 0x152A24)
.text:00152A1C MOVS R2, #0x10
.text:00152A1E MOVS R0, R5
.text:00152A20 ADD R3, PC
.text:00152A22 LDR R3, [R3]
.text:00152A24 ADDS R7, #0x20
.text:00152A26 LDR R1, [R3]
[COLOR="red"].text:00152A28 BLX SHA256_Update[/COLOR]
.text:00152A2C MOVS R1, R5
.text:00152A2E MOV R0, R8
[COLOR="red"].text:00152A30 BLX SHA256_Final[/COLOR]
.text:00152A34 MOVS R0, R7
.text:00152A36 STR R7, [SP,#0x60+var_54]
.text:00152A38 BLX _Znaj ; operator new[](uint)
.text:00152A3C LDR R1, [SP,#0x60+src] ; src
.text:00152A3E MOVS R7, R0
.text:00152A40 MOVS R2, R6 ; n
.text:00152A42 BLX memcpy
.text:00152A46 MOV R1, R8 ; src
.text:00152A48 MOVS R2, #0x20 ; n
.text:00152A4A ADDS R0, R7, R6 ; dest
.text:00152A4C BLX memcpy
.text:00152A50 MOV R0, R9
.text:00152A52 STR R0, [SP,#0x60+var_60]
.text:00152A54 MOVS R1, R7
.text:00152A56 MOV R0, R10
.text:00152A58 LDR R2, [SP,#0x60+var_54]
.text:00152A5A MOV R3, R11
.text:00152A5C BL _ZN13RecordHandler22writeByteArrayAsRecordEPaiib ; RecordHandler::writeByteArrayAsRecord(signed char *,int,int,bool)
.text:00152A60 LDR R0, [SP,#0x60+src] ; void *
.text:00152A62 CMP R0, #0
.text:00152A64 BEQ loc_152A6A
.text:00152A66 BLX _ZdaPv ; operator delete[](void *)
.text:00152A6A
.text:00152A6A loc_152A6A ; CODE XREF: RecordHandler::addHash(int)+C0j
.text:00152A6A MOVS R3, #0
.text:00152A6C STR R3, [SP,#0x60+src]
.text:00152A6E CMP R7, #0
.text:00152A70 BEQ loc_152A78
.text:00152A72 MOVS R0, R7 ; void *
.text:00152A74 BLX _ZdaPv ; operator delete[](void *)
.text:00152A78
.text:00152A78 loc_152A78 ; CODE XREF: RecordHandler::addHash(int)+CCj
.text:00152A78 MOV R1, R8
.text:00152A7A CMP R1, #0
.text:00152A7C BEQ loc_152A84
.text:00152A7E MOV R0, R8 ; void *
.text:00152A80 BLX _ZdaPv ; operator delete[](void *)
.text:00152A84
.text:00152A84 loc_152A84 ; CODE XREF: RecordHandler::addHash(int)+D8j
.text:00152A84 CMP R5, #0
.text:00152A86 BEQ loc_152A8E
.text:00152A88 MOVS R0, R5 ; void *
.text:00152A8A BLX _ZdlPv ; operator delete(void *)
.text:00152A8E
.text:00152A8E loc_152A8E ; CODE XREF: RecordHandler::addHash(int)+30j
.text:00152A8E ; RecordHandler::addHash(int)+E2j
.text:00152A8E LDR R2, [SP,#0x60+var_2C]
.text:00152A90 LDR R3, [R4]
.text:00152A92 CMP R2, R3
.text:00152A94 BNE loc_152AA4
.text:00152A96 ADD SP, SP, #0x3C
.text:00152A98 POP {R2-R5}
.text:00152A9A MOV R8, R2
.text:00152A9C MOV R9, R3
.text:00152A9E MOV R10, R4
.text:00152AA0 MOV R11, R5
.text:00152AA2 POP {R4-R7,PC}
.text:00152AA4 ; ---------------------------------------------------------------------------
.text:00152AA4
.text:00152AA4 loc_152AA4 ; CODE XREF: RecordHandler::addHash(int)+F0j
.text:00152AA4 BLX __stack_chk_fail
.text:00152AA4 ; End of function RecordHandler::addHash(int)

It turns out that SHA256 was used (I've highlighted the relevant flags in the code red) with several rounds of update. Given the time the game was written, I suppose the SHA-2 specification was used (although the SHA-3 specification might also be possible).

However, I will not attempt to dig further any more - I highly suspect from the assembly code that the checksum computation is a function of both the pre-hashed save data and also of certain variables stored in the runtime memory. That being said, additional steps might have to be taken to extract these variables during the game's runtime in order to compute the checksum, something I don't think many people fancy (even if they do, it'll be hell!).

Just in case : for those who are thinking of editing the save files without recomputing the corresponding checksum, don't. The checksum was put in place to ensure that no foreign edits are made to the save files, based on the assumption that no one (other than the game) knows how to compute the checksum. The only way to make foreign edits is to recompute the checksum.