You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.0 KiB

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