Couldn't you just use an UpdateScore() function that when called normally (i.e. the score is not being hacked) it creates an encrypted score based on the score.
When called again, it first checks the current score value in memory against the encrypted score and then verifies that those two are the same - then updates the score and then creates a new encrypted score? If they aren't the same you can do whatever you want - force the game to shutdown, whatever.
Then, when uploading the score, the game can encrypt the actual score with a different key used for the encrypted score - and send both the original (now encrypted) score, and the verification score (the always encrypted version.)
When called again, it first checks the current score value in memory against the encrypted score and then verifies that those two are the same - then updates the score and then creates a new encrypted score? If they aren't the same you can do whatever you want - force the game to shutdown, whatever.
Then, when uploading the score, the game can encrypt the actual score with a different key used for the encrypted score - and send both the original (now encrypted) score, and the verification score (the always encrypted version.)