github.com/cloudflare/circl@v1.5.0/dh/x448/key.go (about)

     1  package x448
     2  
     3  import (
     4  	"crypto/subtle"
     5  
     6  	fp "github.com/cloudflare/circl/math/fp448"
     7  )
     8  
     9  // Size is the length in bytes of a X448 key.
    10  const Size = 56
    11  
    12  // Key represents a X448 key.
    13  type Key [Size]byte
    14  
    15  func (k *Key) clamp(in *Key) *Key {
    16  	*k = *in
    17  	k[0] &= 252
    18  	k[55] |= 128
    19  	return k
    20  }
    21  
    22  // isValidPubKey verifies if the public key is not a low-order point.
    23  func (k *Key) isValidPubKey() bool {
    24  	fp.Modp((*fp.Elt)(k))
    25  	var isLowOrder int
    26  	for _, P := range lowOrderPoints {
    27  		isLowOrder |= subtle.ConstantTimeCompare(P[:], k[:])
    28  	}
    29  	return isLowOrder == 0
    30  }
    31  
    32  // KeyGen obtains a public key given a secret key.
    33  func KeyGen(public, secret *Key) {
    34  	ladderJoye(public.clamp(secret))
    35  }
    36  
    37  // Shared calculates Alice's shared key from Alice's secret key and Bob's
    38  // public key returning true on success. A failure case happens when the public
    39  // key is a low-order point, thus the shared key is all-zeros and the function
    40  // returns false.
    41  func Shared(shared, secret, public *Key) bool {
    42  	validPk := *public
    43  	ok := validPk.isValidPubKey()
    44  	ladderMontgomery(shared.clamp(secret), &validPk)
    45  	return ok
    46  }