pake

package module
v1.1.1 Latest Latest
Warning

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

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

README

pake

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.

Install

go get -u github.com/schollz/pake

Usage

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)
check(err)

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

// 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())
check(err)

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

// 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.

Contributing

Pull requests are welcome. Feel free to...

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

Thanks

Thanks @tscholl2 for implementing the first version.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

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 https://crypto.stanford.edu/~dabo/cryptobook/BonehShoup_0_4.pdf Figure 21/15 http://www.lothar.com/~warner/MagicWormhole-PyCon2016.pdf 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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL