# Does it make any sense to hash parts of a hashing target?

### TL;DR;

Assuming I'm calculating SHA256 for an ECDSA, does it make sense to do SHA256(item1 + SHA256(item1') + item2 + SHA256(item2') + itemN + SHA256(itemN')) or it's the same (security-wise) as SHA256(item1 + item1' + item2 + item2' + itemN + itemN')? (hereunder + refers to as binary concatenation of operands' content in binary format)

### Details

I have a data structure similar to the one below (presenting in JSON format for readability)

{
"Lorem": 123,
"Ipsum": "qwerty",
"Items": [
{
"Id": 4321,
"Data": "SOME_DATA_HERE",
"ItemSig": "A_RELATIVELY_BIG_BINARY_STRUCTURE_AND_ECDSA_SIGNATURE_OF_HELLO_FIELD_CONTENT"
},
{
"Id": 8765,
"Data": "SOME_DATA_HERE",
"ItemSig": "A_RELATIVELY_BIG_BINARY_STRUCTURE_AND_ECDSA_SIGNATURE_OF_HELLO_FIELD_CONTENT"
}
],
"Sig": "A_PLACE_FOR_ECDSA_SIGNATURE"
}


I also have an ECC key pair. Now, I need to sign over each element within the "items" array and then over the entire structure itself.

When signing over the entire structure, I'm proving some data in that structure (contents of Lorem and Ipsum), and per each Item, I'm proving that the item was in that structure (by including Id in the signature) and proving that item's content (by including ItemSig which includes the content).

I think it worth noting that I include ItemSig instead of the item's content in the structure's signature to prove that the item was signed by the same ECC key as the structure itself. This is because there are multiple ECC keys that are valid for signing, but it's considered invalid to sign items with one ECC key while signing the structure with another.

So the question is, what's better option for structure's Sig field (and why?), ECDSA(SHA256(Content)) where

1. Content = Lorem + Ipsum + Items[0].Id + SHA256(Items[0].ItemSig) + Items[1].Id + SHA256(Items[1].ItemSig) + Items[n].Id + SHA256(Items[n].ItemSig), OR
2. Content = Lorem + Ipsum + Items[0].Id + Items[0].ItemSig + Items[1].Id + Items[1].ItemSig + Items[n].Id + Items[n].ItemSig.
• This is because there are multiple ECC keys that are valid for signing??? – kelalaka Jan 13 at 18:45
• @kelalaka sort of - several people own ECC keys that are valid for the operation, but I need to make sure that items and the structure are signed with the same ECC key... I mean even if I had a single ECC key, the question remains the same -- is there any difference whether to use SHA256(item1 + SHA256(item1') + item2 + SHA256(item2') + itemN + SHA256(itemN')) or SHA256(item1 + item1' + item2 + item2' + itemN + itemN') for ECDSA signing? – Nikita Kalinichenko Jan 13 at 21:24
• You can verify the signature only for the signer. What is your issue here? – kelalaka Jan 13 at 22:20
• @kelalaka the issue is that I don't know which of the following is better (and why it's better) ECDSA subject -- SHA256(content+SHA256(content2)+content3+SHA256(content4)) OR SHA256(content+content2+content3+content4), OR they are equivalently good? – Nikita Kalinichenko Jan 13 at 23:51

From the practical point of view both approaches have similar resistance to brute-forcing. From the implementation point of view it may be simpler to apply hash only once, without hashing of every single part.

Nevertheless I would suggest you to review your design and consider other options. Suppose somebody has received your message and validation shows, that Items[0].ItemSig and Items[0].Data to not match. This can have two reasons:

1. Either Items[0].ItemSig was invalid before you signed it (then the signer has faked the signature).
2. Or the signature was correct, but you have replaced Items[0].Data before signing.
3. Or Items[0].Data was modified on the way from you to the receiver.

Thus it will be hard to find out where the problem has happened.

That's why I'd suggest other approach. Think of separation of concerns. Don't consider the structure of what are you signing. Sign the whole element Items. Then if somebody receives your message and something is not consistsnet, it will be easy to check: One should just check if your signature matches the Items element. If matches, means there was no modification on the way from you to the receiver, and the problem occurred on the signer of Items[0].Data before you signed.

TLDR: I'd suggest to hash the whole element Items, not the parts of it, and without hashing of every single part of it.

• Yes, I know that it's a bit odd to sign all those Items one by one and then the entire "batch", and I do agree that it would be better to have one signature instead of n+1, but this is a domain requirement to have a signature for each of those items individually, what I need to do though is to prove that those items were signed within that particular "batch" and batch's metadata (+ prove that batch and items signed by same ECC key). Could you explain how you know that both approaches have similar resistance to brute-forcing? – Nikita Kalinichenko Jan 15 at 13:36
• @NikitaKalinichenko: "one signature instead of n+1" - I didn't said that. I mean, that you should not care what are you signing. You should sign the whole contents of Items element including ItemSig. You should just not care what the content means - is it data, it is signature, is it anything else - just don't care and sign everything as whole. If you sign only some sub-elements, then in case of data modifications it is hard to find out who has modified the data. – mentallurg Jan 15 at 16:39
• @NikitaKalinichenko: ... In case you sign the whole Items element, then it is easy: The receiver checks your signature. If your signature corresponds to the data, this means that inconsistencies are caused not by you. Then the received will talk to the signer of particular element, e.g. why Items[0].ItemSig does not match Items[0].Data. It will be not your responsibility why some signatures don't match data. This will simplify the process for all parties involved in the process. – mentallurg Jan 15 at 16:45
• "From the practical point of view both approaches have similar resistance to brute-forcing." I'm not completely agree, because compute the composed hash is more expensive. Isn't? – Ievgeni Jun 15 at 17:23
• @levgeni: By saying "similar" I mean following. The 1st algorithm needs approximately 4 times more resources than the 2nd one. This difference may look big. But it is feasible for an attacker to find 4 times more resources. Now suppose you use Argon2 and configured it so that the computation of a single hash takes 1s on the same device (for simplicity let's ignore memory factor). – mentallurg Jun 16 at 21:36