From ad029d1293fbec4b687b9b4c5ac63b9e76d9e89b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 20 Jun 2017 16:10:15 +0200 Subject: [PATCH] Integrate ecc into word-byte codec --- keys/wordcodec.go | 39 ++++++++++++++++++++++++++------------- keys/wordcodec_test.go | 20 ++++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/keys/wordcodec.go b/keys/wordcodec.go index b3e45e2c6..7778b9b53 100644 --- a/keys/wordcodec.go +++ b/keys/wordcodec.go @@ -21,6 +21,7 @@ type Codec interface { type WordCodec struct { words []string bytes map[string]int + check ECC } var _ Codec = WordCodec{} @@ -30,7 +31,13 @@ func NewCodec(words []string) (codec WordCodec, err error) { return codec, errors.Errorf("Bank must have %d words, found %d", BankSize, len(words)) } - return WordCodec{words: words}, nil + res := WordCodec{ + words: words, + // TODO: configure this outside??? + check: NewIEEECRC32(), + } + + return res, nil } func LoadCodec(bank string) (codec WordCodec, err error) { @@ -70,6 +77,7 @@ func getData(filename string) (string, error) { // given this many bytes, we will produce this many words func wordlenFromBytes(numBytes int) int { + // 2048 words per bank, which is 2^11. // 8 bits per byte, and we add +10 so it rounds up return (8*numBytes + 10) / 11 } @@ -88,8 +96,9 @@ func bytelenFromWords(numWords int) (length int, maybeShorter bool) { } // TODO: add checksum -func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { - // 2048 words per bank, which is 2^11. +func (c WordCodec) BytesToWords(raw []byte) (words []string, err error) { + // always add a checksum to the data + data := c.check.AddECC(raw) numWords := wordlenFromBytes(len(data)) n2048 := big.NewInt(2048) @@ -106,12 +115,6 @@ func (c WordCodec) BytesToWords(data []byte) (words []string, err error) { } func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { - // // 2048 words per bank, which is 2^11. - // numWords := (8*len(dest) + 10) / 11 - // if numWords != len(words) { - // return errors.New(Fmt("Expected %v words for %v dest bytes", numWords, len(dest))) - // } - l := len(words) n2048 := big.NewInt(2048) nData := big.NewInt(0) @@ -131,10 +134,20 @@ func (c WordCodec) WordsToBytes(words []string) ([]byte, error) { // are lots of leading 0s dataBytes := nData.Bytes() - outLen, _ := bytelenFromWords(len(words)) - output := make([]byte, outLen) - copy(output[outLen-len(dataBytes):], dataBytes) - return output, nil + // copy into the container we have with the expected size + outLen, flex := bytelenFromWords(len(words)) + toCheck := make([]byte, outLen) + copy(toCheck[outLen-len(dataBytes):], dataBytes) + + // validate the checksum... + output, err := c.check.CheckECC(toCheck) + if flex && err != nil { + // if flex, try again one shorter.... + toCheck = toCheck[1:] + output, err = c.check.CheckECC(toCheck) + } + + return output, err } // GetIndex finds the index of the words to create bytes diff --git a/keys/wordcodec_test.go b/keys/wordcodec_test.go index e96912072..e650eb0dd 100644 --- a/keys/wordcodec_test.go +++ b/keys/wordcodec_test.go @@ -54,16 +54,16 @@ func TestEncodeDecode(t *testing.T) { require.Nil(err, "%+v", err) cases := [][]byte{ - // {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes - {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes - {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 - {1, 2, 3, 4, 5}, // normal - // {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) - {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) - {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) - {0, 5, 253, 2, 0}, // leading and trailing zeros - {255, 196, 172, 234, 192, 255}, // big numbers - // {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices + {7, 8, 9}, // TODO: 3 words -> 3 or 4 bytes + {12, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes + {0, 54, 99, 11}, // TODO: 3 words -> 3 or 4 bytes, detect leading 0 + {1, 2, 3, 4, 5}, // normal + {0, 0, 0, 0, 122, 23, 82, 195}, // leading 0s (8 chars, unclear) + {0, 0, 0, 0, 5, 22, 123, 55, 22}, // leading 0s (9 chars, clear) + {22, 44, 55, 1, 13, 0, 0, 0, 0}, // trailing 0s (9 chars, clear) + {0, 5, 253, 2, 0}, // leading and trailing zeros + {255, 196, 172, 234, 192, 255}, // big numbers + {255, 196, 172, 1, 234, 192, 255}, // big numbers, two length choices // others? }