forked from quic-go/quic-go
move fnv128a implementation to separate package
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
package crypto
|
||||
|
||||
// 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.
|
||||
|
||||
// Write() algorithm taken and modified from github.com/romain-jacotin/quic
|
||||
|
||||
import "hash"
|
||||
|
||||
// Hash128 is the common interface implemented by all 128-bit hash functions.
|
||||
type Hash128 interface {
|
||||
hash.Hash
|
||||
Sum128() (uint64, uint64)
|
||||
}
|
||||
|
||||
type sum128a struct {
|
||||
v0, v1, v2, v3 uint64
|
||||
}
|
||||
|
||||
var _ Hash128 = &sum128a{}
|
||||
|
||||
// New128a returns a new 128-bit FNV-1a hash.Hash.
|
||||
func New128a() Hash128 {
|
||||
s := &sum128a{}
|
||||
s.Reset()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *sum128a) Reset() {
|
||||
s.v0 = 0x6295C58D
|
||||
s.v1 = 0x62B82175
|
||||
s.v2 = 0x07BB0142
|
||||
s.v3 = 0x6C62272E
|
||||
}
|
||||
|
||||
func (s *sum128a) Sum128() (uint64, uint64) {
|
||||
return s.v3<<32 | s.v2, s.v1<<32 | s.v0
|
||||
}
|
||||
|
||||
func (s *sum128a) Write(data []byte) (int, error) {
|
||||
var t0, t1, t2, t3 uint64
|
||||
const fnv128PrimeLow = 0x0000013B
|
||||
const fnv128PrimeShift = 24
|
||||
|
||||
for _, v := range data {
|
||||
// xor the bottom with the current octet
|
||||
s.v0 ^= uint64(v)
|
||||
|
||||
// multiply by the 128 bit FNV magic prime mod 2^128
|
||||
// fnv_prime = 309485009821345068724781371 (decimal)
|
||||
// = 0x0000000001000000000000000000013B (hexadecimal)
|
||||
// = 0x00000000 0x01000000 0x00000000 0x0000013B (in 4*32 words)
|
||||
// = 0x0 1<<fnv128PrimeShift 0x0 fnv128PrimeLow
|
||||
//
|
||||
// fnv128PrimeLow = 0x0000013B
|
||||
// fnv128PrimeShift = 24
|
||||
|
||||
// multiply by the lowest order digit base 2^32 and by the other non-zero digit
|
||||
t0 = s.v0 * fnv128PrimeLow
|
||||
t1 = s.v1 * fnv128PrimeLow
|
||||
t2 = s.v2*fnv128PrimeLow + s.v0<<fnv128PrimeShift
|
||||
t3 = s.v3*fnv128PrimeLow + s.v1<<fnv128PrimeShift
|
||||
|
||||
// propagate carries
|
||||
t1 += (t0 >> 32)
|
||||
t2 += (t1 >> 32)
|
||||
t3 += (t2 >> 32)
|
||||
|
||||
s.v0 = t0 & 0xffffffff
|
||||
s.v1 = t1 & 0xffffffff
|
||||
s.v2 = t2 & 0xffffffff
|
||||
s.v3 = t3 // & 0xffffffff
|
||||
// Doing a s.v3 &= 0xffffffff is not really needed since it simply
|
||||
// removes multiples of 2^128. We can discard these excess bits
|
||||
// outside of the loop when writing the hash in Little Endian.
|
||||
}
|
||||
|
||||
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 {
|
||||
panic("FNV: not supported")
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("FNV", func() {
|
||||
It("gives proper null hash", func() {
|
||||
hash := New128a()
|
||||
h, l := hash.Sum128()
|
||||
Expect(l).To(Equal(uint64(0x62b821756295c58d)))
|
||||
Expect(h).To(Equal(uint64(0x6c62272e07bb0142)))
|
||||
})
|
||||
|
||||
It("calculates hash", func() {
|
||||
hash := New128a()
|
||||
_, err := hash.Write([]byte("foobar"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
h, l := hash.Sum128()
|
||||
Expect(l).To(Equal(uint64(0x6f0d3597ba446f18)))
|
||||
Expect(h).To(Equal(uint64(0x343e1662793c64bf)))
|
||||
})
|
||||
})
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
"github.com/lucas-clemente/fnv128a"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
)
|
||||
|
||||
@@ -18,7 +19,7 @@ func (*NullAEAD) Open(packetNumber protocol.PacketNumber, associatedData []byte,
|
||||
return nil, errors.New("NullAEAD: ciphertext cannot be less than 12 bytes long")
|
||||
}
|
||||
|
||||
hash := New128a()
|
||||
hash := fnv128a.New()
|
||||
hash.Write(associatedData)
|
||||
hash.Write(ciphertext[12:])
|
||||
testHigh, testLow := hash.Sum128()
|
||||
@@ -36,7 +37,7 @@ func (*NullAEAD) Open(packetNumber protocol.PacketNumber, associatedData []byte,
|
||||
func (*NullAEAD) Seal(packetNumber protocol.PacketNumber, associatedData []byte, plaintext []byte) []byte {
|
||||
res := make([]byte, 12+len(plaintext))
|
||||
|
||||
hash := New128a()
|
||||
hash := fnv128a.New()
|
||||
hash.Write(associatedData)
|
||||
hash.Write(plaintext)
|
||||
high, low := hash.Sum128()
|
||||
|
||||
Reference in New Issue
Block a user