key.go raw

   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  }
  47