|
|
package blindsecp256k1
import ( "encoding/json" "fmt" "math/big"
"github.com/ethereum/go-ethereum/crypto" )
// swapEndianness swaps the order of the bytes in the slice.
func swapEndianness(b []byte) []byte { o := make([]byte, len(b)) for i := range b { o[len(b)-1-i] = b[i] } return o }
// MarshalJSON implements the json marshaler for the Point
func (p Point) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { X string `json:"x"` Y string `json:"y"` }{ X: p.X.String(), Y: p.Y.String(), }) }
// UnmarshalJSON implements the json unmarshaler for the Point
func (p *Point) UnmarshalJSON(b []byte) error { aux := &struct { X string `json:"x"` Y string `json:"y"` }{} err := json.Unmarshal(b, &aux) if err != nil { return err } x, ok := new(big.Int).SetString(aux.X, 10) if !ok { return fmt.Errorf("Can not parse Point.X %s", aux.X) } y, ok := new(big.Int).SetString(aux.Y, 10) if !ok { return fmt.Errorf("Can not parse Point.Y %s", aux.Y) } p.X = x p.Y = y return nil }
// Bytes returns a byte array of length 64, with the X & Y coordinates of the
// Point encoded in little-endian. [ X (32 bytes) | Y (32 bytes)]
func (p *Point) Bytes() []byte { var b [64]byte copy(b[:32], swapEndianness(p.X.Bytes())) copy(b[32:], swapEndianness(p.Y.Bytes())) return b[:] }
// NewPointFromBytes returns a new *Point from a given byte array with length
// 64 which has encoded the point coordinates each one as 32 bytes in
// little-endian.
func NewPointFromBytes(b []byte) (*Point, error) { if len(b) != 64 { //nolint:gomnd
return nil, fmt.Errorf("Can not parse bytes to Point, expected byte array of length %d, current %d", 64, len(b)) } p := &Point{} p.X = new(big.Int).SetBytes(swapEndianness(b[:32])) p.Y = new(big.Int).SetBytes(swapEndianness(b[32:])) return p, nil }
// MarshalJSON implements the json marshaler for the PublicKey
func (pk PublicKey) MarshalJSON() ([]byte, error) { return json.Marshal(pk.Point()) }
// UnmarshalJSON implements the json unmarshaler for the PublicKey
func (pk *PublicKey) UnmarshalJSON(b []byte) error { var point *Point err := json.Unmarshal(b, &point) if err != nil { return err } pk.X = point.X pk.Y = point.Y return nil }
// Bytes returns a byte array of length 64, with the X & Y coordinates of the
// PublicKey encoded in little-endian. [ X (32 bytes) | Y (32 bytes)]
func (pk *PublicKey) Bytes() []byte { return pk.Point().Bytes() }
// NewPublicKeyFromBytes returns a new *PublicKey from a given byte array with
// length 64 which has encoded the public key coordinates each one as 32 bytes
// in little-endian.
func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { p, err := NewPointFromBytes(b) if err != nil { return nil, err } pk := PublicKey(*p) return &pk, nil }
// NewPublicKeyFromECDSA returns a *PublicKey from a serialized/marshaled array
// of bytes generated by the ethereum/standard ECDSA PubKey implementation.
func NewPublicKeyFromECDSA(b []byte) (*PublicKey, error) { pub, err := crypto.UnmarshalPubkey(b) if err != nil { return nil, err } pk := new(PublicKey) pk.X = pub.X pk.Y = pub.Y return pk, nil }
// MarshalJSON implements the json marshaler for the Signature
func (sig Signature) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { S string `json:"s"` F struct { X string `json:"x"` Y string `json:"y"` } `json:"f"` }{ S: sig.S.String(), F: struct { X string `json:"x"` Y string `json:"y"` }{ X: sig.F.X.String(), Y: sig.F.Y.String(), }, }) }
// UnmarshalJSON implements the json unmarshaler for the Signature
func (sig *Signature) UnmarshalJSON(b []byte) error { aux := &struct { S string `json:"s"` F struct { X string `json:"x"` Y string `json:"y"` } `json:"f"` }{} err := json.Unmarshal(b, &aux) if err != nil { return err }
s, ok := new(big.Int).SetString(aux.S, 10) if !ok { return fmt.Errorf("Can not parse sig.S %s", aux.S) } sig.S = s
x, ok := new(big.Int).SetString(aux.F.X, 10) if !ok { return fmt.Errorf("Can not parse sig.F.X %s", aux.F.X) } y, ok := new(big.Int).SetString(aux.F.Y, 10) if !ok { return fmt.Errorf("Can not parse sig.F.Y %s", aux.F.Y) } sig.F = &Point{} sig.F.X = x sig.F.Y = y return nil }
// Bytes returns a byte array of length 96, with the S, F.X and F.Y coordinates
// of the Signature encoded in little-endian.
// [ S (32 bytes | F.X (32 bytes) | F.Y (32 bytes)]
func (sig *Signature) Bytes() []byte { var b [96]byte copy(b[:32], swapEndianness(sig.S.Bytes())) copy(b[32:96], sig.F.Bytes()) return b[:] }
// NewSignatureFromBytes returns a new *Signature from a given byte array with
// length 96 which has encoded S and the F point coordinates each one as 32
// bytes in little-endian.
func NewSignatureFromBytes(b []byte) (*Signature, error) { if len(b) != 96 { //nolint:gomnd
return nil, fmt.Errorf("Can not parse bytes to Signature, expected byte array of length %d, current %d", 96, len(b)) } s := new(big.Int).SetBytes(swapEndianness(b[:32])) f, err := NewPointFromBytes(b[32:96]) if err != nil { return nil, err } return &Signature{ S: s, F: f, }, nil }
|