Browse Source

Add crc64, constructors

pull/1782/head
Ethan Frey 8 years ago
parent
commit
0b0e994cd1
2 changed files with 84 additions and 4 deletions
  1. +68
    -0
      keys/ecc.go
  2. +16
    -4
      keys/ecc_test.go

+ 68
- 0
keys/ecc.go View File

@ -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
}

+ 16
- 4
keys/ecc_test.go View File

@ -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


Loading…
Cancel
Save