github.com/hhwill/poc-eth@v0.0.0-20240218063348-3bb107c90dbf/crypto/curve25519/api.go (about)

     1  package curve25519
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"crypto/sha256"
     7  	"io"
     8  
     9  	goCurve25519 "golang.org/x/crypto/curve25519"
    10  )
    11  
    12  type Signature [64]byte
    13  
    14  func NewSignature(bytes []byte) (s *Signature) {
    15  	s = new(Signature)
    16  	copy(s[:], bytes)
    17  	return
    18  }
    19  
    20  func (s *Signature) isCanonical() bool {
    21  	return isCanonicalSignature(s[:])
    22  }
    23  
    24  type PublicKey [32]byte
    25  
    26  func NewPublicKey(bytes []byte) (pk *PublicKey) {
    27  	pk = new(PublicKey)
    28  	copy(pk[:], bytes)
    29  	return
    30  }
    31  
    32  func (pk *PublicKey) isCanonical() bool {
    33  	return isCanonicalPublicKey(pk[:])
    34  }
    35  
    36  type PrivateKey struct {
    37  	raw [32]byte
    38  }
    39  
    40  func GenerateKey() (sk *PrivateKey) {
    41  	sk = new(PrivateKey)
    42  	_, _ = io.ReadFull(rand.Reader, sk.raw[:])
    43  	clamp(sk.raw[:])
    44  	return sk
    45  }
    46  
    47  func NewPrivateKey(bytes []byte) (sk *PrivateKey) {
    48  	sk = new(PrivateKey)
    49  	copy(sk.raw[:], bytes)
    50  	clamp(sk.raw[:])
    51  	return sk
    52  }
    53  
    54  func (sk *PrivateKey) toBytes(bytes []byte) []byte {
    55  	if bytes == nil {
    56  		bytes = make([]byte, 32)
    57  	}
    58  	copy(bytes, sk.raw[:])
    59  	return nil
    60  }
    61  
    62  func (sk *PrivateKey) Public() (pk *PublicKey) {
    63  	pk = new(PublicKey)
    64  	goCurve25519.ScalarBaseMult((*[32]byte)(pk), &sk.raw)
    65  	return
    66  }
    67  
    68  func (sk *PrivateKey) SharedSecret(pk *PublicKey) []byte {
    69  	var ss [32]byte
    70  	goCurve25519.ScalarMult(&ss, &sk.raw, (*[32]byte)(pk))
    71  	return ss[:]
    72  }
    73  
    74  func (sk *PrivateKey) myPublic() (pk *PublicKey) {
    75  	pk = new(PublicKey)
    76  	keygen(pk[:], nil, sk.raw[:])
    77  	return
    78  }
    79  
    80  func (sk *PrivateKey) mySharedSecret(pk *PublicKey) (ss []byte) {
    81  	ss = make([]byte, 32)
    82  	curve(ss, sk.raw[:], pk[:])
    83  	return
    84  }
    85  
    86  func (sk *PrivateKey) Sign(message []byte) (signature *Signature) {
    87  	publicKey := make([]byte, 32)
    88  	signingKey := make([]byte, 32)
    89  	keygen(publicKey, signingKey, sk.raw[:])
    90  
    91  	hash := sha256.New()
    92  	hash.Write(message)
    93  	messageDigest := hash.Sum(nil)
    94  
    95  	hash.Reset()
    96  	hash.Write(messageDigest)
    97  	hash.Write(signingKey)
    98  	x := hash.Sum(nil)
    99  	y := make([]byte, 32)
   100  	keygen(y, nil, x)
   101  
   102  	hash.Reset()
   103  	hash.Write(messageDigest)
   104  	hash.Write(y)
   105  	h := hash.Sum(nil)
   106  
   107  	signature = new(Signature)
   108  	sign(signature[:], h, x, signingKey)
   109  	copy(signature[32:], h)
   110  	return
   111  }
   112  
   113  func Verify(message []byte, signature *Signature, pk *PublicKey, enforceCanonical bool) bool {
   114  	if enforceCanonical {
   115  		if !signature.isCanonical() {
   116  			return false
   117  		}
   118  		if !pk.isCanonical() {
   119  			return false
   120  		}
   121  	}
   122  
   123  	Y := make([]byte, 32)
   124  	v := signature[:32]
   125  	h := signature[32:]
   126  
   127  	verify(Y, v, h, pk[:])
   128  
   129  	hash := sha256.New()
   130  	hash.Write(message)
   131  	messageDigest := hash.Sum(nil)
   132  
   133  	hash.Reset()
   134  	hash.Write(messageDigest)
   135  	hash.Write(Y)
   136  	h2 := hash.Sum(nil)
   137  
   138  	return bytes.Equal(h, h2)
   139  }