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.

106 lines
2.6 KiB

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