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.

276 lines
7.0 KiB

  1. package blindsecp256k1
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/big"
  6. "github.com/ethereum/go-ethereum/crypto"
  7. )
  8. // swapEndianness swaps the order of the bytes in the slice.
  9. func swapEndianness(b []byte) []byte {
  10. o := make([]byte, len(b))
  11. for i := range b {
  12. o[len(b)-1-i] = b[i]
  13. }
  14. return o
  15. }
  16. // MarshalJSON implements the json marshaler for the Point
  17. func (p Point) MarshalJSON() ([]byte, error) {
  18. return json.Marshal(&struct {
  19. X string `json:"x"`
  20. Y string `json:"y"`
  21. }{
  22. X: p.X.String(),
  23. Y: p.Y.String(),
  24. })
  25. }
  26. // UnmarshalJSON implements the json unmarshaler for the Point
  27. func (p *Point) UnmarshalJSON(b []byte) error {
  28. aux := &struct {
  29. X string `json:"x"`
  30. Y string `json:"y"`
  31. }{}
  32. err := json.Unmarshal(b, &aux)
  33. if err != nil {
  34. return err
  35. }
  36. x, ok := new(big.Int).SetString(aux.X, 10)
  37. if !ok {
  38. return fmt.Errorf("Can not parse Point.X %s", aux.X)
  39. }
  40. y, ok := new(big.Int).SetString(aux.Y, 10)
  41. if !ok {
  42. return fmt.Errorf("Can not parse Point.Y %s", aux.Y)
  43. }
  44. p.X = x
  45. p.Y = y
  46. return nil
  47. }
  48. // Bytes returns the compressed Point in a little-endian byte array
  49. func (p *Point) Bytes() []byte {
  50. b := p.Compress()
  51. return b[:]
  52. }
  53. // NewPointFromBytes returns a new *Point from a given byte array with length
  54. // 64 which has encoded the point coordinates each one as 32 bytes in
  55. // little-endian.
  56. func NewPointFromBytes(b []byte) (*Point, error) {
  57. if len(b) != 33 { //nolint:gomnd
  58. return nil, fmt.Errorf("Can not parse bytes to Point,"+
  59. " expected byte array of length %d, current %d",
  60. 33, len(b))
  61. }
  62. var pBytes [33]byte
  63. copy(pBytes[:], b[:])
  64. return DecompressPoint(pBytes)
  65. }
  66. // BytesUncompressed returns a byte array of length 64, with the X & Y
  67. // coordinates of the Point encoded in little-endian. [ X (32 bytes) | Y (32
  68. // bytes)]
  69. func (p *Point) BytesUncompressed() []byte {
  70. var b [64]byte
  71. copy(b[:32], swapEndianness(p.X.Bytes()))
  72. copy(b[32:], swapEndianness(p.Y.Bytes()))
  73. return b[:]
  74. }
  75. // NewPointFromBytesUncompressed returns a new *Point from a given byte array
  76. // with length 64 which has encoded the point coordinates each one as 32 bytes
  77. // in little-endian.
  78. func NewPointFromBytesUncompressed(b []byte) (*Point, error) {
  79. if len(b) != 64 { //nolint:gomnd
  80. return nil, fmt.Errorf("Can not parse bytes to Point,"+
  81. " expected byte array of length %d, current %d",
  82. 64, len(b))
  83. }
  84. p := &Point{}
  85. p.X = new(big.Int).SetBytes(swapEndianness(b[:32]))
  86. p.Y = new(big.Int).SetBytes(swapEndianness(b[32:]))
  87. return p, nil
  88. }
  89. // MarshalJSON implements the json marshaler for the PublicKey
  90. func (pk PublicKey) MarshalJSON() ([]byte, error) {
  91. return json.Marshal(pk.Point())
  92. }
  93. // UnmarshalJSON implements the json unmarshaler for the PublicKey
  94. func (pk *PublicKey) UnmarshalJSON(b []byte) error {
  95. var point *Point
  96. err := json.Unmarshal(b, &point)
  97. if err != nil {
  98. return err
  99. }
  100. pk.X = point.X
  101. pk.Y = point.Y
  102. return nil
  103. }
  104. // Bytes returns the compressed PublicKey in a little-endian byte array
  105. func (pk *PublicKey) Bytes() []byte {
  106. return pk.Point().Bytes()
  107. }
  108. // NewPublicKeyFromBytes returns a new *PublicKey from a given byte array with
  109. // length 64 which has encoded the public key coordinates each one as 32 bytes
  110. // in little-endian.
  111. func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) {
  112. p, err := NewPointFromBytes(b)
  113. if err != nil {
  114. return nil, err
  115. }
  116. pk := PublicKey(*p)
  117. return &pk, nil
  118. }
  119. // BytesUncompressed returns a byte array of length 64, with the X & Y
  120. // coordinates of the PublicKey encoded in little-endian.
  121. // [ X (32 bytes) | Y (32 bytes)]
  122. func (pk *PublicKey) BytesUncompressed() []byte {
  123. return pk.Point().BytesUncompressed()
  124. }
  125. // NewPublicKeyFromBytesUncompressed returns a new *PublicKey from a given byte array with
  126. // length 64 which has encoded the public key coordinates each one as 32 bytes
  127. // in little-endian.
  128. func NewPublicKeyFromBytesUncompressed(b []byte) (*PublicKey, error) {
  129. p, err := NewPointFromBytesUncompressed(b)
  130. if err != nil {
  131. return nil, err
  132. }
  133. pk := PublicKey(*p)
  134. return &pk, nil
  135. }
  136. // NewPublicKeyFromECDSA returns a *PublicKey from a serialized/marshaled array
  137. // of bytes generated by the ethereum/standard ECDSA PubKey implementation.
  138. func NewPublicKeyFromECDSA(b []byte) (*PublicKey, error) {
  139. pub, err := crypto.UnmarshalPubkey(b)
  140. if err != nil {
  141. return nil, err
  142. }
  143. pk := new(PublicKey)
  144. pk.X = pub.X
  145. pk.Y = pub.Y
  146. return pk, nil
  147. }
  148. // MarshalJSON implements the json marshaler for the Signature
  149. func (sig Signature) MarshalJSON() ([]byte, error) {
  150. return json.Marshal(&struct {
  151. S string `json:"s"`
  152. F struct {
  153. X string `json:"x"`
  154. Y string `json:"y"`
  155. } `json:"f"`
  156. }{
  157. S: sig.S.String(),
  158. F: struct {
  159. X string `json:"x"`
  160. Y string `json:"y"`
  161. }{
  162. X: sig.F.X.String(),
  163. Y: sig.F.Y.String(),
  164. },
  165. })
  166. }
  167. // UnmarshalJSON implements the json unmarshaler for the Signature
  168. func (sig *Signature) UnmarshalJSON(b []byte) error {
  169. aux := &struct {
  170. S string `json:"s"`
  171. F struct {
  172. X string `json:"x"`
  173. Y string `json:"y"`
  174. } `json:"f"`
  175. }{}
  176. err := json.Unmarshal(b, &aux)
  177. if err != nil {
  178. return err
  179. }
  180. s, ok := new(big.Int).SetString(aux.S, 10)
  181. if !ok {
  182. return fmt.Errorf("Can not parse sig.S %s", aux.S)
  183. }
  184. sig.S = s
  185. x, ok := new(big.Int).SetString(aux.F.X, 10)
  186. if !ok {
  187. return fmt.Errorf("Can not parse sig.F.X %s", aux.F.X)
  188. }
  189. y, ok := new(big.Int).SetString(aux.F.Y, 10)
  190. if !ok {
  191. return fmt.Errorf("Can not parse sig.F.Y %s", aux.F.Y)
  192. }
  193. sig.F = &Point{}
  194. sig.F.X = x
  195. sig.F.Y = y
  196. return nil
  197. }
  198. // Bytes returns the compressed Signature in a little-endian byte array
  199. func (sig *Signature) Bytes() []byte {
  200. s := sig.Compress()
  201. return s[:]
  202. }
  203. // NewSignatureFromBytes returns a new *Signature from a given byte array with
  204. // length 96 which has encoded S and the F point coordinates each one as 32
  205. // bytes in little-endian.
  206. func NewSignatureFromBytes(b []byte) (*Signature, error) {
  207. if len(b) != 65 { //nolint:gomnd
  208. return nil,
  209. fmt.Errorf("Can not parse bytes to Signature,"+
  210. " expected byte array of length %d, current %d",
  211. 65, len(b))
  212. }
  213. s := new(big.Int).SetBytes(swapEndianness(b[:32]))
  214. f, err := NewPointFromBytes(b[32:65])
  215. if err != nil {
  216. return nil, err
  217. }
  218. return &Signature{
  219. S: s,
  220. F: f,
  221. }, nil
  222. }
  223. // BytesUncompressed returns a byte array of length 96, with the S, F.X and F.Y
  224. // coordinates of the Signature encoded in little-endian.
  225. // [ S (32 bytes | F.X (32 bytes) | F.Y (32 bytes)]
  226. func (sig *Signature) BytesUncompressed() []byte {
  227. var b [96]byte
  228. copy(b[:32], swapEndianness(sig.S.Bytes()))
  229. copy(b[32:96], sig.F.BytesUncompressed())
  230. return b[:]
  231. }
  232. // NewSignatureFromBytesUncompressed returns a new *Signature from a given byte array with
  233. // length 96 which has encoded S and the F point coordinates each one as 32
  234. // bytes in little-endian.
  235. func NewSignatureFromBytesUncompressed(b []byte) (*Signature, error) {
  236. if len(b) != 96 { //nolint:gomnd
  237. return nil,
  238. fmt.Errorf("Can not parse bytes to Signature,"+
  239. " expected byte array of length %d, current %d",
  240. 96, len(b))
  241. }
  242. s := new(big.Int).SetBytes(swapEndianness(b[:32]))
  243. f, err := NewPointFromBytesUncompressed(b[32:96])
  244. if err != nil {
  245. return nil, err
  246. }
  247. return &Signature{
  248. S: s,
  249. F: f,
  250. }, nil
  251. }