jpake

package module
v0.0.0-...-b04d6e5 Latest Latest
Warning

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

Go to latest
Published: May 30, 2023 License: MIT Imports: 9 Imported by: 1

README

J-PAKE

Go Reference

This implements https://www.rfc-editor.org/rfc/rfc8236 for go using ECC. Currently only the three-pass variant is implemented. The interface allows for passing in any EC that conforms to Curve[P CurvePoint[P, S], S CurveScalar[S]] interface. At present, only Curve-25519 has a compatible interface. The package filippo.io/edwards25519 provides the underlying implementation used by this interface.

Security considerations

Password selection for J-PAKE is defined as s "a secret value derived from a low-entropy password shared between Alice and Bob". As such, care should be taken to ensure the entropy of that password matches your target application. The configuration provided to the initializing function allows for setting a KDF for both stretching the secret value and the derived session key. The default secret key kdf uses a fixed-salt, so in cases where a low entropy password is used, a different salt should be used.

As well, the default curve used here (curve25519) will panic if given uninitialized inputs. As such, if you use this curve you must recover from this panic in processing any of the J-PAKE steps. For example, the following code could be used within a function calling one of the processing functions:

defer func() {
  if r := recover(); r != nil {
    switch x := r.(type) {
    case string:
      if x == "edwards25519: use of uninitialized Point" {
        err = errors.New(x)
      }
    default:
      panic(r)
    }
  }
}()

For key confirmation, the procedure outlined in the rfc based on NIST SP 800-56A Revision 1 is implemented.

This code is currently unaudited and should not be used in a production setting without a full audit.

Contributing and ackwoledgements

Pull requests are welcome! If you wish to add more curves, add the 2-pass variant or other key confirmation methods, please do, and thanks in advance.

Also thanks to @choonkiatlee for https://github.com/choonkiatlee/jpake-go which was very helpful in making this. This library improves on this by adding support for a user id within the ZKP. As well, it no longer relies on crypto/elliptic (see https://github.com/golang/go/issues/52221).

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Curve25519Params = &CurveParams{
	N: bigFromHex("1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
}

Functions

This section is empty.

Types

type Config

type Config struct {
	// contains filtered or unexported fields
}

func NewConfig

func NewConfig() *Config

func (*Config) SetHashFn

func (c *Config) SetHashFn(h HashFnType) *Config

func (*Config) SetMacFn

func (c *Config) SetMacFn(f MacFnType) *Config

func (*Config) SetSecretGenerationBytes

func (c *Config) SetSecretGenerationBytes(s []byte) *Config

func (*Config) SetSessionConfirmationBytes

func (c *Config) SetSessionConfirmationBytes(scb []byte) *Config

func (*Config) SetSessionGenerationBytes

func (c *Config) SetSessionGenerationBytes(s []byte) *Config

type Curve

type Curve[P CurvePoint[P, S], S CurveScalar[S]] interface {
	Params() *CurveParams
	NewGeneratorPoint() P
	NewRandomScalar(int) (S, error)
	NewScalarFromSecret(int, []byte) (S, error)
	NewPoint() P
	NewScalar() S
	Infinity(P) bool
}

type Curve25519Curve

type Curve25519Curve struct {
	Curve[*Curve25519Point, *Curve25519Scalar]
}

func (Curve25519Curve) Infinity

func (c Curve25519Curve) Infinity(p *Curve25519Point) bool

func (Curve25519Curve) MultiplyScalar

func (c Curve25519Curve) MultiplyScalar(a, b []byte) ([]byte, error)

func (Curve25519Curve) NewGeneratorPoint

func (c Curve25519Curve) NewGeneratorPoint() *Curve25519Point

func (Curve25519Curve) NewPoint

func (c Curve25519Curve) NewPoint() *Curve25519Point

func (Curve25519Curve) NewRandomScalar

func (c Curve25519Curve) NewRandomScalar(l int) (*Curve25519Scalar, error)

func (Curve25519Curve) NewScalar

func (c Curve25519Curve) NewScalar() *Curve25519Scalar

func (Curve25519Curve) NewScalarFromSecret

func (c Curve25519Curve) NewScalarFromSecret(l int, b []byte) (*Curve25519Scalar, error)

func (Curve25519Curve) Params

func (c Curve25519Curve) Params() *CurveParams

type Curve25519Point

type Curve25519Point edwards25519.Point

func (*Curve25519Point) Add

func (*Curve25519Point) Bytes

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

func (*Curve25519Point) Equal

func (p *Curve25519Point) Equal(q *Curve25519Point) int

func (*Curve25519Point) ScalarBaseMult

func (p *Curve25519Point) ScalarBaseMult(s *Curve25519Scalar) (*Curve25519Point, error)

func (*Curve25519Point) ScalarMult

func (*Curve25519Point) SetBytes

func (p *Curve25519Point) SetBytes(b []byte) (*Curve25519Point, error)

func (*Curve25519Point) Subtract

func (p *Curve25519Point) Subtract(r1, r2 *Curve25519Point) *Curve25519Point

type Curve25519Scalar

type Curve25519Scalar edwards25519.Scalar

func (*Curve25519Scalar) BigInt

func (s *Curve25519Scalar) BigInt() *big.Int

func (*Curve25519Scalar) Bytes

func (s *Curve25519Scalar) Bytes() []byte

func (*Curve25519Scalar) Multiply

func (*Curve25519Scalar) SetBigInt

func (s *Curve25519Scalar) SetBigInt(i *big.Int) (*Curve25519Scalar, error)

func (*Curve25519Scalar) SetBytes

func (s *Curve25519Scalar) SetBytes(b []byte) (*Curve25519Scalar, error)

func (*Curve25519Scalar) Zero

func (s *Curve25519Scalar) Zero() bool

type CurveParams

type CurveParams struct {
	N *big.Int
}

type CurvePoint

type CurvePoint[P any, S any] interface {
	Add(r1, r2 P) P
	Subtract(r1, r2 P) P
	ScalarBaseMult(scalar S) (P, error)
	ScalarMult(q P, scalar S) (P, error)
	Bytes() []byte
	SetBytes(b []byte) (P, error)
	Equal(q P) int
}

type CurveScalar

type CurveScalar[S any] interface {
	SetBigInt(*big.Int) (S, error)
	BigInt() *big.Int
	Multiply(S, S) (S, error)
	Bytes() []byte
	SetBytes(b []byte) (S, error)
	Zero() bool
}

type HashFnType

type HashFnType func(in []byte) []byte

type MacFnType

type MacFnType func(key, msg []byte) []byte

type ThreePassJpake

type ThreePassJpake[P CurvePoint[P, S], S CurveScalar[S]] struct {

	// Received Variables
	OtherX1G    P
	OtherX2G    P
	OtherUserID []byte

	SessionKey []byte

	// Private Variables
	X1 S
	X2 S
	S  S

	// configuration
	Stage int
	// contains filtered or unexported fields
}

Three pass variant jpake https://tools.ietf.org/html/rfc8236#section-4 If serializing/deserializing, get/set all exported members

func InitThreePassJpake

func InitThreePassJpake(initiator bool, userID, pw []byte) (*ThreePassJpake[*Curve25519Point, *Curve25519Scalar], error)

func InitThreePassJpakeWithConfig

func InitThreePassJpakeWithConfig(initiator bool, userID, pw []byte, config *Config) (*ThreePassJpake[*Curve25519Point, *Curve25519Scalar], error)

func InitThreePassJpakeWithConfigAndCurve

func InitThreePassJpakeWithConfigAndCurve[P CurvePoint[P, S], S CurveScalar[S]](initiator bool, userID, pw []byte, curve Curve[P, S], config *Config) (*ThreePassJpake[P, S], error)

func RestoreThreePassJpake

func RestoreThreePassJpake(stage int, userID, otherUserID, sessionKey []byte, x1, x2, s *Curve25519Scalar, otherX1G, otherX2G *Curve25519Point) (*ThreePassJpake[*Curve25519Point, *Curve25519Scalar], error)

func RestoreThreePassJpakeWithConfig

func RestoreThreePassJpakeWithConfig(stage int, userID, otherUserID, sessionKey []byte, x1, x2, s *Curve25519Scalar, otherX1G, otherX2G *Curve25519Point, config *Config) (*ThreePassJpake[*Curve25519Point, *Curve25519Scalar], error)

func RestoreThreePassJpakeWithCurveAndConfig

func RestoreThreePassJpakeWithCurveAndConfig[P CurvePoint[P, S], S CurveScalar[S]](stage int, userID, otherUserID, sessionKey []byte, x1, x2, s S, otherX1G, otherX2G P, curve Curve[P, S], config *Config) (*ThreePassJpake[P, S], error)

func (*ThreePassJpake[P, S]) GetPass2Message

func (jp *ThreePassJpake[P, S]) GetPass2Message(msg ThreePassVariant1[P, S]) (*ThreePassVariant2[P, S], error)

func (*ThreePassJpake[P, S]) GetPass3Message

func (jp *ThreePassJpake[P, S]) GetPass3Message(msg ThreePassVariant2[P, S]) (*ThreePassVariant3[P, S], error)

func (*ThreePassJpake[P, S]) Pass1Message

func (jp *ThreePassJpake[P, S]) Pass1Message() (*ThreePassVariant1[P, S], error)

func (*ThreePassJpake[P, S]) ProcessPass3Message

func (jp *ThreePassJpake[P, S]) ProcessPass3Message(msg ThreePassVariant3[P, S]) ([]byte, error)

func (*ThreePassJpake[P, S]) ProcessSessionConfirmation1

func (jp *ThreePassJpake[P, S]) ProcessSessionConfirmation1(confirm1 []byte) ([]byte, error)

func (*ThreePassJpake[P, S]) ProcessSessionConfirmation2

func (jp *ThreePassJpake[P, S]) ProcessSessionConfirmation2(confirm2 []byte) error

type ThreePassVariant1

type ThreePassVariant1[P CurvePoint[P, S], S CurveScalar[S]] struct {
	UserID []byte
	X1G    P
	X2G    P
	X1ZKP  ZKPMsg[P, S]
	X2ZKP  ZKPMsg[P, S]
}

type ThreePassVariant2

type ThreePassVariant2[P CurvePoint[P, S], S CurveScalar[S]] struct {
	UserID []byte
	X3G    P
	X4G    P
	B      P
	XsZKP  ZKPMsg[P, S]
	X3ZKP  ZKPMsg[P, S]
	X4ZKP  ZKPMsg[P, S]
}

type ThreePassVariant3

type ThreePassVariant3[P CurvePoint[P, S], S CurveScalar[S]] struct {
	A     P
	XsZKP ZKPMsg[P, S]
}

type ZKPMsg

type ZKPMsg[P CurvePoint[P, S], S CurveScalar[S]] struct {
	T P
	R S
}

Jump to

Keyboard shortcuts

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