ethereum原理--关于keccak256

2023-10-23 14:46:23 浏览数 (2)

关于 keccak256

看以太坊代码,发现很多地方使用的加密函数是:keccak256,了解了一下做个输出。

Keccak算法(读作为“ket-chak”)是Guido Bertoni, Joan Daemen, Michael Peters, and Giles Van Assche的工作。 SHA-3的候选人在2008年10月提交。 Keccak采用了创新的的“海绵引擎”散列消息文本。它是快速的,在英特尔酷睿2处理器下的平均速度为12.5周期每字节。它设计简单,方便硬件实现。 Keccak已可以抵御最小的复杂度为2n的攻击,其中N为散列的大小。它具有广泛的安全边际。至目前为止,第三方密码分析已经显示出Keccak没有严重的弱点。尽管如此,Keccak的创建者已经启动Crunchy加密比赛,挑起人们发现和报告成功且可核查的攻击Keccak的兴趣。

Keccak-256被设计为于2007年举行的SHA-3密码哈希函数竞赛的候选者。 Keccak是获胜的算法,在2015年被标准化为 FIPS(联邦信息处理标准)。 不过NIST接受原始的Keccak256设计后,更改了Padding的格式,以太坊坚持使用了原始的方案,因为这一更改存在争议,导致了正式的SHA3实现和原始的Keccak不兼容。 NIST一般指美国国家标准与技术研究院。

作用

keccak256算法则可以将任意长度的输入压缩成64位,16进制的数,且哈希碰撞的概率近乎为0.

keccak256 代码结构

sha3加密接口: crypto.go

加密接口在:crypto.go 源码文件中。 KeccakState: 是对 sha3.state 的封装,下面的注释也有说明。还特意提到ReadSum快。

代码语言:javascript复制
// KeccakState wraps sha3.state. In addition to the usual hash methods, it also supports
// Read to get a variable amount of data from the hash state. Read is faster than Sum
// because it doesn't copy the internal state, but also modifies the internal state.
type KeccakState interface {
	hash.Hash
	Read([]byte) (int, error)
}

// Keccak256 calculates and returns the Keccak256 hash of the input data.
func Keccak256(data ...[]byte) []byte {
	b := make([]byte, 32)
	d := sha3.NewLegacyKeccak256().(KeccakState)
	for _, b := range data {
		d.Write(b)
	}
	d.Read(b)
	return b
}

主要方法 Keccak256Hash

作用:Keccak256Hash计算并返回输入数据的Keccak256哈希值,将其转换为一个内部哈希数据结构。

代码语言:javascript复制
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure.
func Keccak256Hash(data ...[]byte) (h common.Hash) {
	d := sha3.NewLegacyKeccak256().(KeccakState)
	for _, b := range data {
		d.Write(b)
	}
	d.Read(h[:])
	return h
}

验证

拿了一下官方测试举例:crypto_test.go

代码语言:javascript复制
// These tests are sanity checks.
// They should ensure that we don't e.g. use Sha3-224 instead of Sha3-256
// and that the sha3 library uses keccak-f permutation.
func TestKeccak256Hash(t *testing.T) {
	msg := []byte("abc")
	exp, _ := hex.DecodeString("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45")
    // 校验结果正确性
	checkhash(t, "Sha3-256-array", func(in []byte) []byte {
		h := Keccak256Hash(in);
		return h[:]
	}, msg, exp)
}

// debug 看下具体内容
func checkhash(t *testing.T, name string, f func([]byte) []byte, msg, exp []byte) {
	sum := f(msg)
	if !bytes.Equal(exp, sum) {
		t.Fatalf("hash %s mismatch: want: %x have: %x", name, exp, sum)
	}
}

以太坊哪些地方使用到了

几乎只要用的数据相关的,都需要进行转换。

将key进行转换

代码语言:javascript复制
func (t *odrTrie) TryGet(key []byte) ([]byte, error) {
	key = crypto.Keccak256(key)
	var res []byte
	err := t.do(key, func() (err error) {
		res, err = t.trie.TryGet(key)
		return err
	})
	return res, err
}

更多调用,所有的也看不完,找到重要的部分阅读。

结论

区块链依赖于加密算法,对加密算法的了解是非常有必要的。全看调用是看不完的,至少需要知道怎么用。 以太坊使用 keccak256 的目的:keccak256算法则可以将任意长度的输入压缩成64位,16进制的数,且哈希碰撞的概率近乎为0.

参考文档

  • 全新的 SHA-3 加密标准 —— Keccak
  • ethereum/crypto_test.go

0 人点赞