package module
Version: v1.1.1 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2019 License: MIT Imports: 9 Imported by: 2



travis go report card coverage godocs

This library will help you allow two parties to generate a mutual secret key by using a weak key that is known to both beforehand (e.g. via some other channel of communication). This is a simple API for an implementation of password-authenticated key exchange (PAKE). This protocol is derived from Dan Boneh and Victor Shoup's cryptography book (pg 789, "PAKE2 protocol). I decided to create this library so I could use PAKE in my file-transfer utility, croc.


go get -u


Explanation of algorithm

// pick an elliptic curve
curve := elliptic.P521() 
// both parties should have a weak key
pw := []byte{1, 2, 3}

// initialize sender P ("0" indicates sender)
P, err := Init(pw, 0, curve)

// initialize recipient Q ("1" indicates recipient)
Q, err := Init(pw, 1, curve)

// first, P sends u to Q
err = Q.Update(P.Bytes())
check(err) // errors will occur when any part of the process fails

// Q computes k, sends H(k), v back to P
err = P.Update(Q.Bytes())

// P computes k, H(k), sends H(k) to Q
err = Q.Update(P.Bytes())

// both P and Q now have session key
k := P.SessionKey()

The H(k) is a bcrypt hashed session key, which only the keeper of a real session key can verify. Passing this between P and Q allows them to understand that the other party does indeed have the session key derived correctly through the PAKE protocol. The session key can then be used to encrypt a message because it has never passed between parties.

When passing P and Q back and forth, the structure is being marshalled using Bytes(), which prevents any private variables from being accessed from either party.

Each function has an error. The error become non-nil when some part of the algorithm fails verification: i.e. the points are not along the elliptic curve, or if a hash from either party is not identified. If this happens, you should abort and start a new PAKE transfer as it would have been compromised.


Pull requests are welcome. Feel free to...

  • Revise documentation
  • Add new features
  • Fix bugs
  • Suggest improvements


Thanks @tscholl2 for implementing the first version.






This section is empty.


This section is empty.


This section is empty.


type EllipticCurve

type EllipticCurve interface {
	Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int)
	ScalarBaseMult(k []byte) (*big.Int, *big.Int)
	ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int)
	IsOnCurve(x, y *big.Int) bool

EllipticCurve is a general curve which allows other elliptic curves to be used with PAKE.

type Pake

type Pake struct {
	// Public variables
	Role     int
	Uᵤ, Uᵥ   *big.Int
	Vᵤ, Vᵥ   *big.Int
	Xᵤ, Xᵥ   *big.Int
	Yᵤ, Yᵥ   *big.Int
	HkA, HkB []byte
	// contains filtered or unexported fields

Pake keeps public and private variables by only transmitting between parties after marshaling.

This method follows Figure 21/15 Slide 11

func Init

func Init(pw []byte, role int, curve EllipticCurve, timeToHash ...time.Duration) (p *Pake, err error)

Init will take the secret weak passphrase (pw) to initialize the points on the elliptic curve. The role is set to either 0 for the sender or 1 for the recipient. The curve can be any elliptic curve.

func InitCurve added in v1.1.0

func InitCurve(pw []byte, role int, curve string, timeToHash ...time.Duration) (p *Pake, err error)

InitCurve will take the secret weak passphrase (pw) to initialize the points on the elliptic curve. The role is set to either 0 for the sender or 1 for the recipient. The curve can be siec, p521, p256, p384

func (*Pake) Bytes

func (p *Pake) Bytes() []byte

Bytes just marshalls the PAKE structure so that private variables are hidden.

func (*Pake) IsVerified

func (p *Pake) IsVerified() bool

IsVerified returns whether or not the k has been generated AND it confirmed to be the same as partner

func (*Pake) SessionKey

func (p *Pake) SessionKey() ([]byte, error)

SessionKey is returned, unless it is not generated in which is returns an error. This function does not check if it is verifies.

func (*Pake) Update

func (p *Pake) Update(qBytes []byte) (err error)

Update will update itself with the other parties PAKE and automatically determine what stage and what to generate.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
t or T : Toggle theme light dark auto
y or Y : Canonical URL