thor icon indicating copy to clipboard operation
thor copied to clipboard

poa/sched.go中产生伪随机数的dprp函数是否存在安全问题?

Open IkarosCoCo opened this issue 5 years ago • 1 comments

func dprp(blockNumber uint32, time uint64) uint64 {
	var (
		b4 [4]byte
		b8 [8]byte
	)
	binary.BigEndian.PutUint32(b4[:], blockNumber)
	binary.BigEndian.PutUint64(b8[:], time)

	return binary.BigEndian.Uint64(thor.Blake2b(b4[:], b8[:]).Bytes())
}

这个函数产生的随机数被用作于选择矿工:

func (s *Scheduler) whoseTurn(t uint64) Proposer {
	index := dprp(s.parentBlockNumber, t) % uint64(len(s.actives))
	return s.actives[index]
}

在这里有个疑问,如果网络稳定的情况下,区块时间间隔应该是保持一致的,即newBlockTime是可预测的,那么是否可以推算出之后所有矿工出块的顺序序列?

IkarosCoCo avatar Jun 10 '19 02:06 IkarosCoCo

对,newBlockTime和矿工出快的顺序序列确实是可以预测的。这在目前来说算是一个小缺陷(幸运的是,攻击的难度并不低),不过对应的改进方案已经有了。

func dprp(blockNumber uint32, time uint64) uint64 {
	var (
		b4 [4]byte
		b8 [8]byte
	)
	binary.BigEndian.PutUint32(b4[:], blockNumber)
	binary.BigEndian.PutUint64(b8[:], time)

	return binary.BigEndian.Uint64(thor.Blake2b(b4[:], b8[:]).Bytes())
}

这个函数产生的随机数被用作于选择矿工:

func (s *Scheduler) whoseTurn(t uint64) Proposer {
	index := dprp(s.parentBlockNumber, t) % uint64(len(s.actives))
	return s.actives[index]
}

在这里有个疑问,如果网络稳定的情况下,区块时间间隔应该是保持一致的,即newBlockTime是可预测的,那么是否可以推算出之后所有矿工出块的顺序序列?

qianbin avatar Jun 10 '19 03:06 qianbin