mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-07 20:40:44 +00:00
Add crc64, constructors
This commit is contained in:
68
keys/ecc.go
68
keys/ecc.go
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"hash/crc32"
|
||||
"hash/crc64"
|
||||
)
|
||||
|
||||
// ECC is used for anything that calculates an error-correcting code
|
||||
@@ -33,6 +34,18 @@ type CRC32 struct {
|
||||
|
||||
var _ ECC = &CRC32{}
|
||||
|
||||
func NewIEEECRC32() *CRC32 {
|
||||
return &CRC32{Poly: crc32.IEEE}
|
||||
}
|
||||
|
||||
func NewCastagnoliCRC32() *CRC32 {
|
||||
return &CRC32{Poly: crc32.Castagnoli}
|
||||
}
|
||||
|
||||
func NewKoopmanCRC32() *CRC32 {
|
||||
return &CRC32{Poly: crc32.Koopman}
|
||||
}
|
||||
|
||||
func (c *CRC32) AddECC(input []byte) []byte {
|
||||
table := c.getTable()
|
||||
|
||||
@@ -71,3 +84,58 @@ func (c *CRC32) getTable() *crc32.Table {
|
||||
}
|
||||
return c.table
|
||||
}
|
||||
|
||||
// CRC64 does the ieee crc64 polynomial check
|
||||
type CRC64 struct {
|
||||
Poly uint64
|
||||
table *crc64.Table
|
||||
}
|
||||
|
||||
var _ ECC = &CRC64{}
|
||||
|
||||
func NewISOCRC64() *CRC64 {
|
||||
return &CRC64{Poly: crc64.ISO}
|
||||
}
|
||||
|
||||
func NewECMACRC64() *CRC64 {
|
||||
return &CRC64{Poly: crc64.ECMA}
|
||||
}
|
||||
|
||||
func (c *CRC64) AddECC(input []byte) []byte {
|
||||
table := c.getTable()
|
||||
|
||||
// get crc and convert to some bytes...
|
||||
crc := crc64.Checksum(input, table)
|
||||
check := make([]byte, crc64.Size)
|
||||
binary.BigEndian.PutUint64(check, crc)
|
||||
|
||||
// append it to the input
|
||||
output := append(input, check...)
|
||||
return output
|
||||
}
|
||||
|
||||
func (c *CRC64) CheckECC(input []byte) ([]byte, error) {
|
||||
table := c.getTable()
|
||||
|
||||
if len(input) <= crc64.Size {
|
||||
return nil, errors.New("input too short, no checksum present")
|
||||
}
|
||||
cut := len(input) - crc64.Size
|
||||
data, check := input[:cut], input[cut:]
|
||||
crc := binary.BigEndian.Uint64(check)
|
||||
calc := crc64.Checksum(data, table)
|
||||
if crc != calc {
|
||||
return nil, errors.New("Checksum does not match")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (c *CRC64) getTable() *crc64.Table {
|
||||
if c.table == nil {
|
||||
if c.Poly == 0 {
|
||||
c.Poly = crc64.ISO
|
||||
}
|
||||
c.table = crc64.MakeTable(c.Poly)
|
||||
}
|
||||
return c.table
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -13,7 +12,14 @@ import (
|
||||
func TestECCPasses(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
checks := []ECC{NoECC{}, &CRC32{}, &CRC32{Poly: crc32.Castagnoli}}
|
||||
checks := []ECC{
|
||||
NoECC{},
|
||||
NewIEEECRC32(),
|
||||
NewCastagnoliCRC32(),
|
||||
NewKoopmanCRC32(),
|
||||
NewISOCRC64(),
|
||||
NewECMACRC64(),
|
||||
}
|
||||
|
||||
for _, check := range checks {
|
||||
for i := 0; i < 2000; i++ {
|
||||
@@ -22,7 +28,7 @@ func TestECCPasses(t *testing.T) {
|
||||
|
||||
checked := check.AddECC(data)
|
||||
res, err := check.CheckECC(checked)
|
||||
if assert.Nil(err, "%v: %+v", check, err) {
|
||||
if assert.Nil(err, "%#v: %+v", check, err) {
|
||||
assert.Equal(data, res, "%v", check)
|
||||
}
|
||||
}
|
||||
@@ -33,7 +39,13 @@ func TestECCPasses(t *testing.T) {
|
||||
func TestECCFails(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
checks := []ECC{&CRC32{}, &CRC32{Poly: crc32.Castagnoli}}
|
||||
checks := []ECC{
|
||||
NewIEEECRC32(),
|
||||
NewCastagnoliCRC32(),
|
||||
NewKoopmanCRC32(),
|
||||
NewISOCRC64(),
|
||||
NewECMACRC64(),
|
||||
}
|
||||
|
||||
attempts := 2000
|
||||
|
||||
|
||||
Reference in New Issue
Block a user