arnaucube
arnaucube/go-iden3-cryptoPublic Self-hosted repository
go-iden3-crypto/utils/utils.go
utils/utils.goRaw
  1package utils
  2
  3import (
  4	"bytes"
  5	"encoding/hex"
  6	"fmt"
  7	"math/big"
  8	"strings"
  9
 10	"github.com/iden3/go-iden3-crypto/constants"
 11	"github.com/iden3/go-iden3-crypto/ff"
 12)
 13
 14// NewIntFromString creates a new big.Int from a decimal integer encoded as a
 15// string.  It will panic if the string is not a decimal integer.
 16func NewIntFromString(s string) *big.Int {
 17	v, ok := new(big.Int).SetString(s, 10)
 18	if !ok {
 19		panic(fmt.Sprintf("Bad base 10 string %s", s))
 20	}
 21	return v
 22}
 23
 24// SwapEndianness swaps the endianness of the value encoded in xs.  If xs is
 25// Big-Endian, the result will be Little-Endian and viceversa.
 26func SwapEndianness(xs []byte) []byte {
 27	ys := make([]byte, len(xs))
 28	for i, b := range xs {
 29		ys[len(xs)-1-i] = b
 30	}
 31	return ys
 32}
 33
 34// BigIntLEBytes encodes a big.Int into an array in Little-Endian.
 35func BigIntLEBytes(v *big.Int) [32]byte {
 36	le := SwapEndianness(v.Bytes())
 37	res := [32]byte{}
 38	copy(res[:], le)
 39	return res
 40}
 41
 42// SetBigIntFromLEBytes sets the value of a big.Int from a Little-Endian
 43// encoded value.
 44func SetBigIntFromLEBytes(v *big.Int, leBuf []byte) *big.Int {
 45	beBuf := SwapEndianness(leBuf)
 46	return v.SetBytes(beBuf)
 47}
 48
 49// Hex is a byte slice type that can be marshalled and unmarshaled in hex
 50type Hex []byte
 51
 52// MarshalText encodes buf as hex
 53func (buf Hex) MarshalText() ([]byte, error) {
 54	return []byte(hex.EncodeToString(buf)), nil
 55}
 56
 57// String encodes buf as hex
 58func (buf Hex) String() string {
 59	return hex.EncodeToString(buf)
 60}
 61
 62// HexEncode encodes an array of bytes into a string in hex.
 63func HexEncode(bs []byte) string {
 64	return fmt.Sprintf("0x%s", hex.EncodeToString(bs))
 65}
 66
 67// HexDecode decodes a hex string into an array of bytes.
 68func HexDecode(h string) ([]byte, error) {
 69	h = strings.TrimPrefix(h, "0x")
 70	return hex.DecodeString(h)
 71}
 72
 73// HexDecodeInto decodes a hex string into an array of bytes (dst), verifying
 74// that the decoded array has the same length as dst.
 75func HexDecodeInto(dst []byte, h []byte) error {
 76	if bytes.HasPrefix(h, []byte("0x")) {
 77		h = h[2:]
 78	}
 79	if len(h)/2 != len(dst) {
 80		return fmt.Errorf("expected %v bytes in hex string, got %v", len(dst), len(h)/2)
 81	}
 82	n, err := hex.Decode(dst, h)
 83	if err != nil {
 84		return err
 85	} else if n != len(dst) {
 86		return fmt.Errorf("expected %v bytes when decoding hex string, got %v", len(dst), n)
 87	}
 88	return nil
 89}
 90
 91// CheckBigIntInField checks if given *big.Int fits in a Field Q element
 92func CheckBigIntInField(a *big.Int) bool {
 93	return a.Cmp(constants.Q) == -1
 94}
 95
 96// CheckBigIntArrayInField checks if given *big.Int fits in a Field Q element
 97func CheckBigIntArrayInField(arr []*big.Int) bool {
 98	for _, a := range arr {
 99		if !CheckBigIntInField(a) {
100			return false
101		}
102	}
103	return true
104}
105
106func BigIntArrayToElementArray(bi []*big.Int) []*ff.Element {
107	var o []*ff.Element
108	for i := range bi {
109		o = append(o, ff.NewElement().SetBigInt(bi[i]))
110	}
111	return o
112}