// Package diffiehellman povides Diffie-Hellman-Merkle key exchange.
package diffiehellman
import (
"crypto/rand"
"log"
"math/big"
)
// PrivateKey returns a number in range(1, p).
func PrivateKey(p *big.Int) *big.Int {
ret := new(big.Int)
for {
var err error
ret, err = rand.Int(rand.Reader, p)
if err != nil {
log.Fatalf("error generating random number")
}
if ret.Cmp(big.NewInt(1)) > 0 && ret.Cmp(p) < 0 {
break
}
}
return ret
}
// PublicKey return a public key.
func PublicKey(private, p *big.Int, g int64) *big.Int {
// key = g**private mod p
key := new(big.Int)
key.Exp(big.NewInt(g), private, p)
return key
}
// NewPair returns a key pair (public+private)
func NewPair(p *big.Int, g int64) (private, public *big.Int) {
private = PrivateKey(p)
public = PublicKey(private, p, g)
return private, public
}
// SecretKey returns the secret key.
func SecretKey(private1, public2, p *big.Int) *big.Int {
// s = public2 ** private1 mod p == public1 ** private2 mod p
s := new(big.Int)
s.Exp(public2, private1, p)
return s
}