mirror of
https://github.com/status-im/status-go.git
synced 2025-01-16 01:35:10 +00:00
eeca435064
Update vendor Integrate rendezvous into status node Add a test with failover using rendezvous Use multiple servers in client Use discovery V5 by default and test that node can be started with rendezvous discovet Fix linter Update rendezvous client to one with instrumented stream Address feedback Fix test with updated topic limits Apply several suggestions Change log to debug for request errors because we continue execution Remove web3js after rebase Update rendezvous package
225 lines
3.9 KiB
Go
225 lines
3.9 KiB
Go
// Package keccak implements the Keccak (SHA-3) hash algorithm.
|
|
// http://keccak.noekeon.org.
|
|
package keccakpg
|
|
|
|
import (
|
|
_ "fmt"
|
|
"hash"
|
|
)
|
|
|
|
const stdRounds = 24
|
|
|
|
var roundConstants = []uint64{
|
|
0x0000000000000001, 0x0000000000008082,
|
|
0x800000000000808A, 0x8000000080008000,
|
|
0x000000000000808B, 0x0000000080000001,
|
|
0x8000000080008081, 0x8000000000008009,
|
|
0x000000000000008A, 0x0000000000000088,
|
|
0x0000000080008009, 0x000000008000000A,
|
|
0x000000008000808B, 0x800000000000008B,
|
|
0x8000000000008089, 0x8000000000008003,
|
|
0x8000000000008002, 0x8000000000000080,
|
|
0x000000000000800A, 0x800000008000000A,
|
|
0x8000000080008081, 0x8000000000008080,
|
|
0x0000000080000001, 0x8000000080008008,
|
|
}
|
|
|
|
var rotationConstants = [24]uint{
|
|
1, 3, 6, 10, 15, 21, 28, 36,
|
|
45, 55, 2, 14, 27, 41, 56, 8,
|
|
25, 43, 62, 18, 39, 61, 20, 44,
|
|
}
|
|
|
|
var piLane = [24]uint{
|
|
10, 7, 11, 17, 18, 3, 5, 16,
|
|
8, 21, 24, 4, 15, 23, 19, 13,
|
|
12, 2, 20, 14, 22, 9, 6, 1,
|
|
}
|
|
|
|
type keccak struct {
|
|
S [25]uint64
|
|
size int
|
|
blockSize int
|
|
rounds int
|
|
buf []byte
|
|
}
|
|
|
|
func newKeccak(bitlen, rounds int) hash.Hash {
|
|
var h keccak
|
|
h.size = bitlen / 8
|
|
h.blockSize = (200 - 2*h.size)
|
|
h.rounds = rounds
|
|
if rounds != stdRounds {
|
|
//fmt.Printf("keccak: warning non standard number of rounds %d vs %d\n", rounds, stdRounds)
|
|
}
|
|
return &h
|
|
}
|
|
|
|
func NewCustom(bits, rounds int) hash.Hash {
|
|
return newKeccak(bits, rounds)
|
|
}
|
|
|
|
func New160() hash.Hash {
|
|
return newKeccak(160, stdRounds)
|
|
}
|
|
|
|
func New224() hash.Hash {
|
|
return newKeccak(224, stdRounds)
|
|
}
|
|
|
|
func New256() hash.Hash {
|
|
return newKeccak(256, stdRounds)
|
|
}
|
|
|
|
func New384() hash.Hash {
|
|
return newKeccak(384, stdRounds)
|
|
}
|
|
|
|
func New512() hash.Hash {
|
|
return newKeccak(512, stdRounds)
|
|
}
|
|
|
|
func (k *keccak) Write(b []byte) (int, error) {
|
|
n := len(b)
|
|
|
|
if len(k.buf) > 0 {
|
|
x := k.blockSize - len(k.buf)
|
|
if x > len(b) {
|
|
x = len(b)
|
|
}
|
|
k.buf = append(k.buf, b[:x]...)
|
|
b = b[x:]
|
|
|
|
if len(k.buf) < k.blockSize {
|
|
return n, nil
|
|
}
|
|
|
|
k.f(k.buf)
|
|
k.buf = nil
|
|
}
|
|
|
|
for len(b) >= k.blockSize {
|
|
k.f(b[:k.blockSize])
|
|
b = b[k.blockSize:]
|
|
}
|
|
|
|
k.buf = b
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func (k0 *keccak) Sum(b []byte) []byte {
|
|
|
|
k := *k0
|
|
|
|
last := k.pad(k.buf)
|
|
k.f(last)
|
|
|
|
buf := make([]byte, len(k.S)*8)
|
|
for i := range k.S {
|
|
putUint64le(buf[i*8:], k.S[i])
|
|
}
|
|
return append(b, buf[:k.size]...)
|
|
}
|
|
|
|
func (k *keccak) Reset() {
|
|
for i := range k.S {
|
|
k.S[i] = 0
|
|
}
|
|
k.buf = nil
|
|
}
|
|
|
|
func (k *keccak) Size() int {
|
|
return k.size
|
|
}
|
|
|
|
func (k *keccak) BlockSize() int {
|
|
return k.blockSize
|
|
}
|
|
|
|
func rotl64(x uint64, n uint) uint64 {
|
|
return (x << n) | (x >> (64 - n))
|
|
}
|
|
|
|
func (k *keccak) f(block []byte) {
|
|
|
|
if len(block) != k.blockSize {
|
|
panic("f() called with invalid block size")
|
|
}
|
|
|
|
for i := 0; i < k.blockSize/8; i++ {
|
|
k.S[i] ^= uint64le(block[i*8:])
|
|
}
|
|
|
|
for r := 0; r < k.rounds; r++ {
|
|
var bc [5]uint64
|
|
|
|
// theta
|
|
for i := range bc {
|
|
bc[i] = k.S[i] ^ k.S[5+i] ^ k.S[10+i] ^ k.S[15+i] ^ k.S[20+i]
|
|
}
|
|
for i := range bc {
|
|
t := bc[(i+4)%5] ^ rotl64(bc[(i+1)%5], 1)
|
|
for j := 0; j < len(k.S); j += 5 {
|
|
k.S[i+j] ^= t
|
|
}
|
|
}
|
|
|
|
// rho phi
|
|
temp := k.S[1]
|
|
for i := range piLane {
|
|
j := piLane[i]
|
|
temp2 := k.S[j]
|
|
k.S[j] = rotl64(temp, rotationConstants[i])
|
|
temp = temp2
|
|
}
|
|
|
|
// chi
|
|
for j := 0; j < len(k.S); j += 5 {
|
|
for i := range bc {
|
|
bc[i] = k.S[j+i]
|
|
}
|
|
for i := range bc {
|
|
k.S[j+i] ^= (^bc[(i+1)%5]) & bc[(i+2)%5]
|
|
}
|
|
}
|
|
|
|
// iota
|
|
k.S[0] ^= roundConstants[r]
|
|
}
|
|
}
|
|
|
|
func (k *keccak) pad(block []byte) []byte {
|
|
|
|
padded := make([]byte, k.blockSize)
|
|
|
|
copy(padded, k.buf)
|
|
padded[len(k.buf)] = 0x01
|
|
padded[len(padded)-1] |= 0x80
|
|
|
|
return padded
|
|
}
|
|
|
|
func uint64le(v []byte) uint64 {
|
|
return uint64(v[0]) |
|
|
uint64(v[1])<<8 |
|
|
uint64(v[2])<<16 |
|
|
uint64(v[3])<<24 |
|
|
uint64(v[4])<<32 |
|
|
uint64(v[5])<<40 |
|
|
uint64(v[6])<<48 |
|
|
uint64(v[7])<<56
|
|
|
|
}
|
|
|
|
func putUint64le(v []byte, x uint64) {
|
|
v[0] = byte(x)
|
|
v[1] = byte(x >> 8)
|
|
v[2] = byte(x >> 16)
|
|
v[3] = byte(x >> 24)
|
|
v[4] = byte(x >> 32)
|
|
v[5] = byte(x >> 40)
|
|
v[6] = byte(x >> 48)
|
|
v[7] = byte(x >> 56)
|
|
}
|