func (private *Private) recompute() (err error) { acceptable := extra25519.ScalarBaseMult(&private.public, &private.uniform, (*[32]byte)(&private.private)) if !acceptable { err = ErrBadPrivateKey } return }
func dhKeypairGen() (*[32]byte, *[32]byte) { priv := new([32]byte) pub := new([32]byte) repr := new([32]byte) reprFound := false for !reprFound { if _, err := Rand.Read(priv[:]); err != nil { log.Fatalln("Error reading random for DH private key:", err) } reprFound = extra25519.ScalarBaseMult(pub, repr, priv) } return priv, repr }
// NewKeypair generates a new Curve25519 keypair, and optionally also generates // an Elligator representative of the public key. func NewKeypair(elligator bool) (*Keypair, error) { keypair := new(Keypair) keypair.private = new(PrivateKey) keypair.public = new(PublicKey) if elligator { keypair.representative = new(Representative) } for { // Generate a Curve25519 private key. Like everyone who does this, // run the CSPRNG output through SHA256 for extra tinfoil hattery. priv := keypair.private.Bytes()[:] if err := csrand.Bytes(priv); err != nil { return nil, err } digest := sha256.Sum256(priv) digest[0] &= 248 digest[31] &= 127 digest[31] |= 64 copy(priv, digest[:]) if elligator { // Apply the Elligator transform. This fails ~50% of the time. if !extra25519.ScalarBaseMult(keypair.public.Bytes(), keypair.representative.Bytes(), keypair.private.Bytes()) { continue } } else { // Generate the corresponding Curve25519 public key. curve25519.ScalarBaseMult(keypair.public.Bytes(), keypair.private.Bytes()) } return keypair, nil } }