forked from quic-go/quic-go
add a very simplistic and slow FNV-128a implementation
This commit is contained in:
13
crypto/crypto_suite_test.go
Normal file
13
crypto/crypto_suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package crypto_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCrypto(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "Crypto Suite")
|
||||||
|
}
|
||||||
64
crypto/fnv.go
Normal file
64
crypto/fnv.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package crypto
|
||||||
|
|
||||||
|
// Taken and modified from https://golang.org/src/hash/fnv/fnv.go
|
||||||
|
// TODO: This implementation uses big ints and is probably horrendously slow.
|
||||||
|
|
||||||
|
// Implements FNV-1 and FNV-1a, non-cryptographic hash functions
|
||||||
|
// created by Glenn Fowler, Landon Curt Noll, and Phong Vo.
|
||||||
|
// See https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hash128 is the common interface implemented by all 128-bit hash functions.
|
||||||
|
type Hash128 interface {
|
||||||
|
hash.Hash
|
||||||
|
Sum128() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type sum128a struct {
|
||||||
|
*big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Hash128 = &sum128a{}
|
||||||
|
|
||||||
|
var offset128 = &big.Int{}
|
||||||
|
var prime128 = &big.Int{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
offset128.SetString("144066263297769815596495629667062367629", 0)
|
||||||
|
prime128.SetString("309485009821345068724781371", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// New128a returns a new 128-bit FNV-1a hash.Hash.
|
||||||
|
func New128a() Hash128 {
|
||||||
|
i := &big.Int{}
|
||||||
|
i.Set(offset128)
|
||||||
|
return &sum128a{i}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sum128a) Reset() { s.Set(offset128) }
|
||||||
|
|
||||||
|
func (s *sum128a) Sum128() []byte { return s.Bytes() }
|
||||||
|
|
||||||
|
func (s *sum128a) Write(data []byte) (int, error) {
|
||||||
|
for _, c := range data {
|
||||||
|
s.Xor(s.Int, big.NewInt(int64(c)))
|
||||||
|
s.Mul(s.Int, prime128)
|
||||||
|
|
||||||
|
// Truncate the bigint to 128 bits
|
||||||
|
s.SetBytes(s.Bytes()[len(s.Bytes())-16 : len(s.Bytes())])
|
||||||
|
}
|
||||||
|
return len(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sum128a) Size() int { return 16 }
|
||||||
|
|
||||||
|
func (s *sum128a) BlockSize() int { return 1 }
|
||||||
|
|
||||||
|
func (s *sum128a) Sum(in []byte) []byte {
|
||||||
|
b := s.Bytes()
|
||||||
|
return append(in, b[len(b)-s.Size():]...)
|
||||||
|
}
|
||||||
21
crypto/fnv_test.go
Normal file
21
crypto/fnv_test.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package crypto_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/lucas-clemente/quic-go/crypto"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("FNV", func() {
|
||||||
|
It("gives proper null hash", func() {
|
||||||
|
h := crypto.New128a()
|
||||||
|
Expect(h.Sum128()).To(Equal([]byte{0x6c, 0x62, 0x27, 0x2e, 0x07, 0xbb, 0x01, 0x42, 0x62, 0xb8, 0x21, 0x75, 0x62, 0x95, 0xc5, 0x8d}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("gives hashes", func() {
|
||||||
|
h := crypto.New128a()
|
||||||
|
h.Write([]byte("foobar"))
|
||||||
|
Expect(h.Sum128()).To(Equal([]byte{0x34, 0x3e, 0x16, 0x62, 0x79, 0x3c, 0x64, 0xbf, 0x6f, 0xd, 0x35, 0x97, 0xba, 0x44, 0x6f, 0x18}))
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user