개요
Go의 라이브러리에서 사용하는 SHA3-512 해시값과 자바스립트에서 사용하는 CryptoJS의 SHA3-512 해시값이 다른 문제가 발생
테스트 대상 모듈
테스트 방법
Go의 테스트 코드 작성 후 Go에서 생성한 해시값과 Javascript에서 위의 라이브러리로 생성했을 때 해시값이 같은지 비교한다.
테스트 결과
- hash.js : SHA3-512 관련 함수가 없는 것 같았다.
- js-sha3 : 성공
- CrytoJS : 실패
CrytoJS 의 경우 Go에서 사용하는 SHA3-512와 차이가 있는 것 같다. cryptojs_document에 참고 사항이 있었다.
NOTE: I made a mistake when I named this implementation SHA-3. It should be named Keccak[c=2d]. Each of the SHA-3 functions is based on an instance of the Keccak algorithm, which NIST selected as the winner of the SHA-3 competition, but those SHA-3 functions won’t produce hashes identical to Keccak.
Go 테스트 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
func TestSha3(t *testing.T) {
addr, _ := utils.FromHex("079164CF59F8B91DA6EC0767CB78075D73E93994")
tx, _ := utils.FromHex("D08BC04E9EDACA0D964BF7404CD1E9C4939C1F099F26177B9B8597BC521BC5CE")
shashum1 := sha3.New512()
shashum1.Write(addr)
println("[addr to sha3-512] ", utils.ToHex(shashum1.Sum(nil), false))
shashum2 := sha3.New512()
shashum2.Write(tx)
println("[txHash to sha3-512] ", utils.ToHex(shashum2.Sum(nil), false))
hasher512 := sha3.New512()
hasher512.Write(addr)
hasher512.Write(tx)
sha512 := hasher512.Sum(nil)
hasher160 := ripemd160.New()
_, _ = hasher160.Write(sha512)
println("[data-account] ", utils.ToHex(hasher160.Sum(nil), false))
}
|
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
test("Test sha3-512", () => {
const u8Addr = Hex.toU8Array('079164CF59F8B91DA6EC0767CB78075D73E93994');
const expected_sha3_512 = 'A6CEF82C523F10ABE2684E19FD1AB35580E8B2DCE4926280B6CEC829D2A1A734F46A642BAA5C62369F185577D23A8428D50C201842B62663DCEB1EF2CD911853';
// js-sha3 (pass)
const shasum = sha3_512.create()
shasum.update(u8Addr)
shasum.hex()
expect(shasum.toString().toUpperCase()).toEqual(expected_sha3_512)
// hashjs (fail)
const shasum2 = hashjs.sha512().update(u8Addr).digest('hex')
console.log(shasum2.toUpperCase())
expect(shasum2.toUpperCase()).toEqual(expected_sha3_512)
// CRYPTOJS (fail)
const shasum3 = CryptoJS.SHA3.create(u8Addr, {outputLength: 512});
expect(shasum3.toUpperCase()).toEqual(expected_sha3_512)
});
|
결론 및 답변 내용
SHA-3은 SHA-1과 SHA-2를 대체하기 위해 미국 국립표준기술연구소(NIST)가 공개적인 방식을 통해 선정한 암호화 해시 함수이다. 최종 적으로 Keccak
이 SHA-3의 해시 알고리즘으로 선정되었고 그 이후 NIST에서 변경된 암호화 해시 함수 표준을 발표했다. 결과적으로 처음 선정되었던 Keccak
방식과 현재 공식적인 SHA3 방식이 일부 달라지게 되었다.
- CryptoJS 에서 구현한 SHA3은 공식적인 SHA3이 아니라 이전 SHA3(Keccak)으로 보임.
js-sha3
라이브러리가 추가됨에 따라 최적화가 필요하므로 hash-wasm
라이브러리를 추천해주심.