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 }