tzhash/gf127/gf127.go
Evgeniy Kulikov 5cf44c62ac
Initial
2018-12-29 16:04:17 +03:00

103 lines
2.3 KiB
Go

// Copyright 2018 (c) NSPCC
//
// Package gf127 implements the GF(2^127) arithmetic
// modulo reduction polynomial x^127 + x^63 + 1 .
// This is rather straight-forward re-implementation of C library
// available here https://github.com/srijs/hwsl2-core .
// Interfaces are highly influenced by math/big .
package gf127
import (
"encoding/binary"
"encoding/hex"
"errors"
)
// GF127 represents element of GF(2^127)
type GF127 [2]uint64
const msb64 = 0x8000000000000000
const byteSize = 16
// x127x64 represents x^127 + x^63. Used in assembly file.
var x127x63 = GF127{msb64, msb64}
// New constructs new element of GF(2^127) as hi*x^64 + lo.
// It is assumed that hi has zero MSB.
func New(lo, hi uint64) *GF127 {
return &GF127{lo, hi}
}
// 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
}
// Mul sets c to the product a*b and returns c.
func (c *GF127) Mul(a, b *GF127) *GF127 {
Mul(a, b, c)
return c
}
// Add sets c to the sum a+b and returns c.
func (c *GF127) Add(a, b *GF127) *GF127 {
Add(a, b, c)
return c
}
// Mul1 copies a to b.
func Mul1(a, b *GF127) {
b[0] = a[0]
b[1] = a[1]
}
// And sets c to a & b (bitwise-and).
func And(a, b, c *GF127) {
c[0] = a[0] & b[0]
c[1] = a[1] & b[1]
}
// Add sets c to a+b.
func Add(a, b, c *GF127)
// Mul sets c to a*b.
func Mul(a, b, c *GF127)
// Mul10 sets y to a*x.
func Mul10(a, b *GF127)
// Mul11 sets y to a*(x+1).
func Mul11(a, b *GF127)