Hash malleability issue because of JSON serialization
- Dominant language
- Go
- Stars
- 44
- Forks
- 12
- PR merge metrics
- No merged PRs in 30d
Description
Today @soonkuk approached me with an issue regarding [a WIP commit](https://github.com/soonkuk/sebak/commit/5b1c22ae32c2f581651ef4566fb8af415e1a46c1)
The integration tests were failing for no apparent reason. From the code it was obvious this came from [adding an empty struct to the operation body](https://github.com/soonkuk/sebak/commit/5b1c22ae32c2f581651ef4566fb8af415e1a46c1#diff-64dcdb85b4f0936552aff214b5b9cbcaR12) which changed the hash.
Indeed, the transaction that sebak would generate was:
```json
{
"T": "transaction",
"H": {
"version": "",
"created": "2018-09-17T02:28:45.183923554Z",
"hash": "GEgcpwUHVrSM5McEsccfSdnM3r4MALX3SbfShcHdmAQK",
"signature": "3yXsyrCnarBz1azSd1ymhPjmnRjDz8Mo4oydoJEaWPsMz4rVmLmvYwfM315z7hy5fep9sd3s2JGHjobAiAN9mdjm"
},
"B": {
"source": "GDIRF4UWPACXPPI4GW7CMTACTCNDIKJEHZK44RITZB4TD3YUM6CCVNGJ",
"fee": "10000",
"sequenceID": 0,
"operations": [
{
"H": {
"type": "create-account"
},
"B": {
"target": "GDTEPFWEITKFHSUO44NQABY2XHRBBH2UBVGJ2ZJPDREIOL2F6RAEBJE4",
"amount": "10000000000"
}
}
]
}
}
```
while the transaction recorded in the test suite was:
```json
{
"T": "transaction",
"H": {
"version": "",
"created": "2018-01-01T00:00:00.000000000Z",
"hash": "B9n71T2RwHPFY7uyZKZh9tXCdRCHAngakoZQXw5ZExfQ",
"signature": "5zdcFUaYAXZ7ZNyKWzfw2b9GENS65mFtgXC4KVcXhJWAARGAHLa1faewwdCEMuQVgaHQojd6r86svXP8xn4zKvCT"
},
"B": {
"source": "GDIRF4UWPACXPPI4GW7CMTACTCNDIKJEHZK44RITZB4TD3YUM6CCVNGJ",
"fee": "10000",
"sequenceID": 0,
"operations": [
{
"H": {
"type": "create-account"
},
"B": {
"target": "GDTEPFWEITKFHSUO44NQABY2XHRBBH2UBVGJ2ZJPDREIOL2F6RAEBJE4",
"amount": "10000000000"
}
}
]
}
}
```
(the date difference can be simply ignored)
Notice how the hash (and subsequently, signature) changes despite the transaction being the same.
This is because we produce the hash based on the actual struct rather than the serialized data, and json has some features (e.g. `omitempty`) which can lead to the same transaction having different hashes, which is not something we want.
Contributor guide
Research direction
Start with the integration tests and the transaction structs involved in JSON serialization, reproducing the differing hashes for the two equivalent transactions shown here. The work is done when equivalent transaction data produces one stable hash and signature and the integration tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- blockchain, cryptography
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100