spake2plus

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

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

Go to latest
Published: Oct 2, 2020 License: MIT Imports: 11 Imported by: 0

README

spake2plus

RFC

SPAKE2+ has been detached from its joint definition in RFC standard with SPAKE2. While SPAKE2 is used for peer-to-peer communication, SPAKE2+ is ideal for Client-Server Authentication.

From the current RFC:

SPAKE2+ is an augmented PAKE protocol, as only one party (Client/A) makes direct use of the password during the execution of the protocol. The other party (Server/B) only needs a verification value at the time of the protocol execution instead of the password.

SPAKE2+ Trace:

                  A                           B

                  |         (Preamble)        |
                  |<- - - - - - - - - - - - ->|
                  |                           |
                  |       (setup protocol)    |
     (compute pA) |             pA            |
                  |-------------------------->|
                  |             pB            | (compute pB)
                  |<--------------------------|
                  |                           |
                  |       (derive secrets)    | (compute cB)
                  |             cB            |
                  |<--------------------------|
     (compute cA) |             cA            |
                  |-------------------------->|

SPAKE2+ is a two round protocol that establishes a shared secret with an additional round for key confirmation. The Preamble part (suite and h2c definition, etc., used by both server and client) is beyond the scope of the RFC, and so is this repo.

The Client and Server instance will have to assume that the other party uses the same.

The Registration part in test is part of the Preamble Exchange where the verifier materials and Identity will be sent and stored by the server on a non-volatile DB. This exchange part of the protocol had to be secured by both parties and not defined in RFC.

The lookup DB provided here is just an in-memory K-V map.

This is only a benchmark/study for SPAKE2+ that closely follows the most recent RFC with all the recommended CipherSuites.

Dependencies:

  1. Cloudflare's CIRCL - For P384 (amd64) and Ed448

  2. Scrypt and Argon2id are given as MHF options. (see spake2.go)

To-Do:

  1. Context

Disclaimer

!!DON'T USE THIS IN PRODUCTION!!

This is used for benchmarking all suites. RFC changes over time. Moreover, Golang's P384 and P521 aren't constant time, so is big.Int, and I also cannot vouch for the stability of the dependencies listed here.

Benchmark

goarch: amd64
pkg: github.com/jtejido/spake2plus
BenchmarkSPAKE2PlusEd25519Scrypt-4                   722           1648622 ns/op
BenchmarkSPAKE2PlusEd448Scrypt-4                     298           4146113 ns/op
BenchmarkSPAKE2PlusP256Sha256Scrypt-4                576           1999250 ns/op
BenchmarkSPAKE2PlusP384Sha256Scrypt-4                129           9088915 ns/op
BenchmarkSPAKE2PlusP256Sha512Scrypt-4                624           2063409 ns/op
BenchmarkSPAKE2PlusP384Sha512Scrypt-4                128           9129860 ns/op
BenchmarkSPAKE2PlusP521Sha512Scrypt-4                 10         104200010 ns/op
PASS

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Argon2

func Argon2(time, memory uint32, threads uint8) suite.MHF

func Ed25519Sha256HkdfHmac

func Ed25519Sha256HkdfHmac(mhf suite.MHF) suite.CipherSuite

func Ed448Sha512HkdfHmac

func Ed448Sha512HkdfHmac(mhf suite.MHF) suite.CipherSuite

func P256Sha256HkdfHmac

func P256Sha256HkdfHmac(mhf suite.MHF) suite.CipherSuite

func P256Sha512HkdfHmac

func P256Sha512HkdfHmac(mhf suite.MHF) suite.CipherSuite

func P384Sha256HkdfHmac

func P384Sha256HkdfHmac(mhf suite.MHF) suite.CipherSuite

func P384Sha512HkdfHmac

func P384Sha512HkdfHmac(mhf suite.MHF) suite.CipherSuite

func P521Sha512HkdfHmac

func P521Sha512HkdfHmac(mhf suite.MHF) suite.CipherSuite

func Scrypt

func Scrypt(N, r, p int) suite.MHF

MHFs

Types

type Client

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

func NewClient

func NewClient(s suite.CipherSuite, clientIdentity, serverIdentity, password, salt []byte) (*Client, error)

func (*Client) CompleteHandshake

func (c *Client) CompleteHandshake(m *ServerMaterial) (*SharedSecret, error)

func (*Client) EphemeralPublic

func (c *Client) EphemeralPublic() ([]byte, error)

EphemeralPublic returns A. This will be sent to the server.

func (*Client) Verifier

func (c *Client) Verifier() (*Verifier, error)

Send this to server during Registration part

type Confirmations

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

Confirmations provides a easy interface for confirmation verification, for state load.

func NewConfirmations

func NewConfirmations(confirmation, remoteConfirmation []byte, suite suite.CipherSuite) *Confirmations

NewConfirmations creates a Confirmations.

func (Confirmations) Bytes

func (c Confirmations) Bytes() []byte

Bytes gets the confirmation message.

func (Confirmations) Verify

func (c Confirmations) Verify(incomingConfirmation []byte) error

Verify verifies an incoming confirmation message.

type Lookup

type Lookup interface {
	Fetch(username []byte) (*UserInfo, bool)
}

type MapLookup

type MapLookup map[string]*UserInfo

in-memory DB user Lookup implementation to be used by the Server. This is the place where a valid user registration is stored (identity-verifier) User's info should be fetched from a non-volatile DB. This is here primarily for tests. Don't use

func NewMapLookup

func NewMapLookup() *MapLookup

func (*MapLookup) Add

func (m *MapLookup) Add(uname []byte, v *Verifier) error

Add a user to the database with the Verifier and Group type.

func (*MapLookup) Fetch

func (m *MapLookup) Fetch(username []byte) (*UserInfo, bool)

Context?

type Server

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

func NewServer

func NewServer(s suite.CipherSuite, lookup Lookup, serverIdentity []byte) (*Server, error)

func (*Server) Handshake

func (s *Server) Handshake(identity, A []byte) (*ServerMaterial, *SharedSecret, error)

type ServerMaterial

type ServerMaterial struct {
	B []byte
}

ServerMaterial is what you send out to the client A so it can verify the confirmation against the given B and secret key known only to A. SPAKE2+ reference says that we can send it all in one go. This saves an extra round.

type SharedSecret

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

func (SharedSecret) Bytes

func (s SharedSecret) Bytes() []byte

func (*SharedSecret) Confirmation

func (s *SharedSecret) Confirmation() []byte

send this to server once verification is complete

func (*SharedSecret) Verify

func (s *SharedSecret) Verify(incomingConfirmation []byte) error

Verify verifies an incoming confirmation message.

type UserInfo

type UserInfo struct {
	Verifier *Verifier
}

type Verifier

type Verifier struct {
	// identity with a verifier. To be stored on a non-volatile DB.
	I        []byte
	Verifier VerifierPair
}

func (*Verifier) Encode

func (v *Verifier) Encode() (string, string)

Encode the verifier into a portable format - returns a tuple <Identity, VerifierPair> as portable strings. The caller can store the Verifier against the Identity in non-volatile storage. An SRP client will supply Identity and its public key - whereupon, an SRP server will use the Identity as a key to lookup the rest of the encoded verifier data.

type VerifierPair

type VerifierPair struct {
	V1, V2 []byte
}

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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