gospake2

package module
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 11 Imported by: 0

README

gospake2

An implementation of the Spake2 password-authenticated key exchange protocol as described in RFC 9382 in Go.

Overview

Spake2 is a secure password-authenticated key exchange protocol that allows two parties that share a weak password to derive a strong shared key without disclosing the password.

Implementation

gospake2 provides a default ciphersuite for use with the Spake2 protocol as the variable DEFAULT_SUITE It uses the edwards25519 curve as its group, SHA256 as its hash function, SHA512 to hash the provided password, HKDF for its key derivation function, and HMAC for its Message Authentication Code algorithm

Note:

SHA512 as the password hash function provided by the default ciphersuite is NOT MEMORY-HARD and is NOT the recomended hash function for any secure application. It is included in DEFAULT_SUITE due to its speed for low-security applications

Usage

First, both sides are initialized with the same password and messages containing pA and pB are created

package main

import spake2 "github.com/ValiantChip/gospake2"

a := spake2.NewA(password, "A", "B", rand.Reader, spake2.DEFAULT_SUITE)
amsg, err := a.Start()
//handle err

b := spake2.NewB(password, "A", "B", rand.Reader, spake2.DEFAULT_SUITE)
bmsg, err := b.Start()
//handle err

The messages are then exchanged between a and b and the shared key and confirmation messages are created

K_a, aConf, err := a.Finish(bmsg)
//handle err

K_b, bConf, err := b.Finish(amsg)
//handle err

The confirmation messages are then shared between a and b and are verified to determine if the protocol was successful

err := a.Verify(bConf)
//handle err

err := b.Verify(aConf)
//hand err

The protocol is now complete and a and b have the shared key K

Installation

Use go get to install this package

go get github.com/ValiantChip/gospake2

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAlreadyStarted     = errors.New("instance has already been started")
	ErrNotStarted         = errors.New("instance has not been started")
	ErrAlreadyFinished    = errors.New("instance has already been finished")
	ErrNotFinished        = errors.New("instance has not been finished")
	ErrVerificationFailed = errors.New("verification failed")
)
View Source
var DEFAULT_SUITE = CipherSuite[*ed25519.Point, *ed25519.Scalar, *ed25519.Curve]{
	Group:        new(ed25519.Curve),
	Hash:         sha256.New,
	PasswordHash: sha512.New,
	Kdf:          hkdf.Key[hash.Hash],
	Mac:          hmac.MAC,
}

DEFAULT_SUITE is the default ciphersuite for use in Spake2 Note: sha512 is not Memory-Hard and is not recommended by rfc9382

Functions

This section is empty.

Types

type CipherSuite

type CipherSuite[W Point[W, S], S Scalar[S], G Group[W, S]] struct {
	Group        G
	Hash         func() hash.Hash
	PasswordHash func() hash.Hash
	Kdf          func(h func() hash.Hash, ikm []byte, salt []byte, info string, L int) ([]byte, error)
	Mac          func(h func() hash.Hash, key, msg []byte) []byte
}

CipherSuite is a ciphersuite for the Spake2 protocol

func NewCipherSuite

func NewCipherSuite[W Point[W, S], S Scalar[S], G Group[W, S]](
	group G,
	hash func() hash.Hash,
	passwordHash func() hash.Hash,
	kdf func(h func() hash.Hash, ikm, salt []byte, info string, L int) ([]byte, error),
	mac func(h func() hash.Hash, key, msg []byte) []byte,
) CipherSuite[W, S, G]

Creates a new CipherSuite

type Group

type Group[P Point[P, S], S Scalar[S]] interface {
	NewGeneratorPoint() P
	NewIdentityPoint() P
	NewMPoint() P
	NewNPoint() P
	NewPoint() P
	NewScalar() S
}

type Point

type Point[P any, S any] interface {
	Add(p, q P) P
	Subtract(p, q P) P
	Bytes() []byte
	MultByCofactor(p P) P
	ScalarMult(x S, p P) P
	ScalarBaseMult(x S) P
	Set(p P) P
	SetBytes(x []byte) (P, error)
}

type Scalar

type Scalar[S any] interface {
	Add(x, y S) S
	Subtract(x, y S) S
	Bytes() []byte
	Multiply(x, y S) S
	Set(x S) S
	SetUniformBytes(x []byte) (S, error)
}

type Spake2A

type Spake2A[W Point[W, S], S Scalar[S], G Group[W, S]] struct {
	// contains filtered or unexported fields
}

represents A in the Spake2 protocol

func NewA

func NewA[W Point[W, S], S Scalar[S], G Group[W, S]](pw []byte, A, B string, rand io.Reader, c CipherSuite[W, S, G]) (*Spake2A[W, S, G], error)

Creates a new instance of A pw is a slice of bytes known to both A and B A and B are strings that are shared between A and B

func (*Spake2A[W, S, G]) Finish

func (s *Spake2A[W, S, G]) Finish(msg []byte) (key, cmsg []byte, err error)

Returns thre shared secret key and the confirmation message from the Spake2 protocol Key is the shared secret returned from the protocol Cmsg is the confirmation message to send to B for key confirmation Confirmation if the message to be compared to the message recieved from B for key confirmation

func (*Spake2A[W, S, G]) Start

func (s *Spake2A[W, S, G]) Start() ([]byte, error)

Starts the protocol for A and returns the byte slice representation of pA If Start() has already been called on this instance ofA ErrAlreadyStarted will be returned

func (*Spake2A[W, S, G]) Verify

func (s *Spake2A[W, S, G]) Verify(msg []byte) error

Verifies the confirmation message from A If the verification fails ErrVerificationFailed will be returned If the instance has not been finished ErrNotFinished will be returned

type Spake2B

type Spake2B[W Point[W, S], S Scalar[S], G Group[W, S]] struct {
	// contains filtered or unexported fields
}

Represents B in the Spake2 protocol

func NewB

func NewB[S Scalar[S], W Point[W, S], G Group[W, S]](pw []byte, A string, B string, rand io.Reader, c CipherSuite[W, S, G]) (*Spake2B[W, S, G], error)

Creates a new instance of B pw is a slice of bytes known to both A and B A and B are strings that are shared between A and B

func (*Spake2B[W, S, G]) Finish

func (s *Spake2B[W, S, G]) Finish(msg []byte) (key, cmsg []byte, err error)

Returns thre shared secret key and the confirmation message from the Spake2 protocol Key is the shared secret returned from the protocol Cmsg is the confirmation message to send to A for key confirmation Confirmation if the message to be compared to the message recieved from A for key confirmation

func (*Spake2B[W, S, G]) Start

func (s *Spake2B[W, S, G]) Start() ([]byte, error)

Starts the protocol for B and returns the byte slice representation of pA If Start() has already been called on this instance of B ErrAlreadyStarted will be returned

func (*Spake2B[W, S, G]) Verify

func (s *Spake2B[W, S, G]) Verify(msg []byte) error

Verifies the confirmation message from A If the verification fails ErrVerificationFailed will be returned If the instance has not been finished ErrNotFinished will be returned

type Spake2Handler

type Spake2Handler interface {
	Start() ([]byte, error)
	Finish(msg []byte) ([]byte, []byte, error)
	Verify(msg []byte) error
}

Represents an object that can handle the Spake2 protocol

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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