2018-12-29 13:04:17 +00:00
|
|
|
package gf127
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"encoding/hex"
|
|
|
|
"errors"
|
2019-01-29 11:25:17 +00:00
|
|
|
"math/rand"
|
2018-12-29 13:04:17 +00:00
|
|
|
)
|
|
|
|
|
2019-01-29 11:11:08 +00:00
|
|
|
const (
|
2019-10-15 09:10:39 +00:00
|
|
|
byteSize = 16
|
|
|
|
maxUint64 = ^uint64(0)
|
|
|
|
msb64 = uint64(1) << 63
|
2019-01-29 11:11:08 +00:00
|
|
|
)
|
|
|
|
|
2019-10-15 09:10:39 +00:00
|
|
|
// GF127 represents element of GF(2^127)
|
|
|
|
type GF127 [2]uint64
|
2018-12-29 13:04:17 +00:00
|
|
|
|
2019-01-29 11:25:17 +00:00
|
|
|
// Random returns random element from GF(2^127).
|
|
|
|
// Is used mostly for testing.
|
|
|
|
func Random() *GF127 {
|
|
|
|
return &GF127{rand.Uint64(), rand.Uint64() >> 1}
|
|
|
|
}
|
|
|
|
|
2018-12-29 13:04:17 +00:00
|
|
|
// String returns hex-encoded representation, starting with MSB.
|
|
|
|
func (c *GF127) String() string {
|
|
|
|
return hex.EncodeToString(c.ByteArray())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equals checks if two reduced (zero MSB) elements of GF(2^127) are equal
|
|
|
|
func (c *GF127) Equals(b *GF127) bool {
|
|
|
|
return c[0] == b[0] && c[1] == b[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
// ByteArray represents element of GF(2^127) as byte array of length 16.
|
|
|
|
func (c *GF127) ByteArray() (buf []byte) {
|
|
|
|
buf = make([]byte, 16)
|
|
|
|
binary.BigEndian.PutUint64(buf[:8], c[1])
|
|
|
|
binary.BigEndian.PutUint64(buf[8:], c[0])
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalBinary implements encoding.BinaryMarshaler.
|
|
|
|
func (c *GF127) MarshalBinary() (data []byte, err error) {
|
|
|
|
return c.ByteArray(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
|
|
|
func (c *GF127) UnmarshalBinary(data []byte) error {
|
|
|
|
if len(data) != byteSize {
|
|
|
|
return errors.New("data must be 16-bytes long")
|
|
|
|
}
|
|
|
|
|
|
|
|
c[0] = binary.BigEndian.Uint64(data[8:])
|
|
|
|
c[1] = binary.BigEndian.Uint64(data[:8])
|
|
|
|
if c[1]&msb64 != 0 {
|
|
|
|
return errors.New("MSB must be zero")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|