forked from toolshed/abra
		
	
		
			
				
	
	
		
			92 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package eddsa implements EdDSA signature, suitable for OpenPGP, as specified in
 | |
| // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh-06#section-13.7
 | |
| package eddsa
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
 | |
| 	"io"
 | |
| )
 | |
| 
 | |
| type PublicKey struct {
 | |
| 	X     []byte
 | |
| 	curve ecc.EdDSACurve
 | |
| }
 | |
| 
 | |
| type PrivateKey struct {
 | |
| 	PublicKey
 | |
| 	D []byte
 | |
| }
 | |
| 
 | |
| func NewPublicKey(curve ecc.EdDSACurve) *PublicKey {
 | |
| 	return &PublicKey{
 | |
| 		curve: curve,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func NewPrivateKey(key PublicKey) *PrivateKey {
 | |
| 	return &PrivateKey{
 | |
| 		PublicKey: key,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (pk *PublicKey) GetCurve() ecc.EdDSACurve {
 | |
| 	return pk.curve
 | |
| }
 | |
| 
 | |
| func (pk *PublicKey) MarshalPoint() []byte {
 | |
| 	return pk.curve.MarshalBytePoint(pk.X)
 | |
| }
 | |
| 
 | |
| func (pk *PublicKey) UnmarshalPoint(x []byte) error {
 | |
| 	pk.X = pk.curve.UnmarshalBytePoint(x)
 | |
| 
 | |
| 	if pk.X == nil {
 | |
| 		return errors.New("eddsa: failed to parse EC point")
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (sk *PrivateKey) MarshalByteSecret() []byte {
 | |
| 	return sk.curve.MarshalByteSecret(sk.D)
 | |
| }
 | |
| 
 | |
| func (sk *PrivateKey) UnmarshalByteSecret(d []byte) error {
 | |
| 	sk.D = sk.curve.UnmarshalByteSecret(d)
 | |
| 
 | |
| 	if sk.D == nil {
 | |
| 		return errors.New("eddsa: failed to parse scalar")
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func GenerateKey(rand io.Reader, c ecc.EdDSACurve) (priv *PrivateKey, err error) {
 | |
| 	priv = new(PrivateKey)
 | |
| 	priv.PublicKey.curve = c
 | |
| 	priv.PublicKey.X, priv.D, err = c.GenerateEdDSA(rand)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func Sign(priv *PrivateKey, message []byte) (r, s []byte, err error) {
 | |
| 	sig, err := priv.PublicKey.curve.Sign(priv.PublicKey.X, priv.D, message)
 | |
| 	if err != nil {
 | |
| 		return nil, nil, err
 | |
| 	}
 | |
| 
 | |
| 	r, s = priv.PublicKey.curve.MarshalSignature(sig)
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func Verify(pub *PublicKey, message, r, s []byte) bool {
 | |
| 	sig := pub.curve.UnmarshalSignature(r, s)
 | |
| 	if sig == nil {
 | |
| 		return false
 | |
| 	}
 | |
| 
 | |
| 	return pub.curve.Verify(pub.X, message, sig)
 | |
| }
 | |
| 
 | |
| func Validate(priv *PrivateKey) error {
 | |
| 	return priv.curve.ValidateEdDSA(priv.PublicKey.X, priv.D)
 | |
| }
 |