github.com/storacha/go-ucanto@v0.7.2/principal/ed25519/verifier/verifier.go (about)

     1  package verifier
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ed25519"
     6  	"fmt"
     7  
     8  	"github.com/multiformats/go-varint"
     9  	"github.com/storacha/go-ucanto/did"
    10  	"github.com/storacha/go-ucanto/principal"
    11  	"github.com/storacha/go-ucanto/principal/multiformat"
    12  	"github.com/storacha/go-ucanto/ucan/crypto/signature"
    13  )
    14  
    15  const Code = 0xed
    16  const Name = "Ed25519"
    17  
    18  const SignatureCode = signature.EdDSA
    19  const SignatureAlgorithm = "EdDSA"
    20  
    21  var publicTagSize = varint.UvarintSize(Code)
    22  
    23  const keySize = 32
    24  
    25  var size = publicTagSize + keySize
    26  
    27  func Parse(str string) (principal.Verifier, error) {
    28  	did, err := did.Parse(str)
    29  	if err != nil {
    30  		return nil, fmt.Errorf("parsing DID: %w", err)
    31  	}
    32  	return Decode(did.Bytes())
    33  }
    34  
    35  func Decode(b []byte) (principal.Verifier, error) {
    36  	if len(b) != size {
    37  		return nil, fmt.Errorf("invalid length: %d wanted: %d", len(b), size)
    38  	}
    39  
    40  	puc, err := varint.ReadUvarint(bytes.NewReader(b))
    41  	if err != nil {
    42  		return nil, fmt.Errorf("reading public key codec: %w", err)
    43  	}
    44  	if puc != Code {
    45  		return nil, fmt.Errorf("invalid public key codec: %d", puc)
    46  	}
    47  
    48  	v := make(Ed25519Verifier, size)
    49  	copy(v, b)
    50  
    51  	return v, nil
    52  }
    53  
    54  // FromRaw takes raw ed25519 public key bytes and tags with the ed25519 verifier
    55  // multiformat code, returning an ed25519 verifier.
    56  func FromRaw(b []byte) (principal.Verifier, error) {
    57  	if len(b) != ed25519.PublicKeySize {
    58  		return nil, fmt.Errorf("invalid length: %d wanted: %d", len(b), ed25519.PublicKeySize)
    59  	}
    60  	return Ed25519Verifier(multiformat.TagWith(Code, b)), nil
    61  }
    62  
    63  type Ed25519Verifier []byte
    64  
    65  func (v Ed25519Verifier) Code() uint64 {
    66  	return Code
    67  }
    68  
    69  func (v Ed25519Verifier) Verify(msg []byte, sig signature.Signature) bool {
    70  	if sig.Code() != signature.EdDSA {
    71  		return false
    72  	}
    73  	return ed25519.Verify(ed25519.PublicKey(v[publicTagSize:]), msg, sig.Raw())
    74  }
    75  
    76  func (v Ed25519Verifier) DID() did.DID {
    77  	id, _ := did.Decode(v)
    78  	return id
    79  }
    80  
    81  func (v Ed25519Verifier) Encode() []byte {
    82  	return v
    83  }
    84  
    85  func (s Ed25519Verifier) Raw() []byte {
    86  	k := make(ed25519.PublicKey, ed25519.PublicKeySize)
    87  	copy(k, s[publicTagSize:])
    88  	return k
    89  }