87 lines
1.7 KiB
Go
87 lines
1.7 KiB
Go
package types
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
)
|
|
|
|
const SignatureMaxLength = 200
|
|
|
|
type Signature crypto.Signature
|
|
|
|
func SignatureFromBytes(x []byte) (Signature, error) {
|
|
val, nr := binary.Uvarint(x)
|
|
if nr != 1 {
|
|
return Signature{}, fmt.Errorf("signatures with type field longer than one byte are invalid")
|
|
}
|
|
|
|
return Signature{
|
|
Type: crypto.SigType(val),
|
|
Data: x[1:],
|
|
}, nil
|
|
}
|
|
|
|
func (s *Signature) MarshalCBOR(w io.Writer) error {
|
|
if s == nil {
|
|
_, err := w.Write(cbg.CborNull)
|
|
return err
|
|
}
|
|
|
|
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(s.Data)+1))
|
|
|
|
if _, err := w.Write(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := w.Write([]byte{byte(s.Type)}); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := w.Write(s.Data); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *Signature) UnmarshalCBOR(br io.Reader) error {
|
|
maj, l, err := cbg.CborReadHeader(br)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if maj != cbg.MajByteString {
|
|
return fmt.Errorf("cbor input for signature was not a byte string")
|
|
}
|
|
|
|
if l > SignatureMaxLength {
|
|
return fmt.Errorf("cbor byte array for signature was too long")
|
|
}
|
|
|
|
buf := make([]byte, l)
|
|
if _, err := io.ReadFull(br, buf); err != nil {
|
|
return err
|
|
}
|
|
|
|
if buf[0] != byte(crypto.SigTypeSecp256k1) && buf[0] != byte(crypto.SigTypeBLS) {
|
|
return fmt.Errorf("invalid signature type in cbor input: %d", buf[0])
|
|
}
|
|
|
|
s.Type = crypto.SigType(buf[0])
|
|
s.Data = buf[1:]
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *Signature) Equals(o *Signature) bool {
|
|
if s == nil || o == nil {
|
|
return s == o
|
|
}
|
|
return s.Type == o.Type && bytes.Equal(s.Data, o.Data)
|
|
}
|