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	if strings.HasPrefix(h, "0x") {
 70		h = h[2:]
 71	}
 72	return hex.DecodeString(h)
 73}
 74
 75// HexDecodeInto decodes a hex string into an array of bytes (dst), verifying
 76// that the decoded array has the same length as dst.
 77func HexDecodeInto(dst []byte, h []byte) error {
 78	if bytes.HasPrefix(h, []byte("0x")) {
 79		h = h[2:]
 80	}
 81	if len(h)/2 != len(dst) {
 82		return fmt.Errorf("expected %v bytes in hex string, got %v", len(dst), len(h)/2)
 83	}
 84	n, err := hex.Decode(dst, h)
 85	if err != nil {
 86		return err
 87	} else if n != len(dst) {
 88		return fmt.Errorf("expected %v bytes when decoding hex string, got %v", len(dst), n)
 89	}
 90	return nil
 91}
 92
 93// CheckBigIntInField checks if given *big.Int fits in a Field Q element
 94func CheckBigIntInField(a *big.Int) bool {
 95	if a.Cmp(constants.Q) != -1 {
 96		return false
 97	}
 98	return true
 99}
100
101// CheckBigIntArrayInField checks if given *big.Int fits in a Field Q element
102func CheckBigIntArrayInField(arr []*big.Int) bool {
103	for _, a := range arr {
104		if !CheckBigIntInField(a) {
105			return false
106		}
107	}
108	return true
109}
110
111// CheckElementArrayInField checks if given *ff.Element fits in a Field Q element
112func CheckElementArrayInField(arr []*ff.Element) bool {
113	for _, aE := range arr {
114		a := big.NewInt(0)
115		aE.ToBigIntRegular(a)
116		if !CheckBigIntInField(a) {
117			return false
118		}
119	}
120	return true
121}
122
123func NewElement() *ff.Element {
124	return &ff.Element{0, 0, 0, 0}
125}