spake2-0.4.2: Implementation of the SPAKE2 Password-Authenticated Key Exchange algorithm

Safe HaskellNone






class Group group => AbelianGroup group where Source #

A group where elementAdd is commutative.

That is, where

\x y -> elementAdd group x y == elementAdd group y x

This property leads to a natural \(\mathbb{Z}\)-module, where scalar multiplication is defined as repeatedly calling elementAdd.


Warning: this gets algebraic.

A module is a ring \(R\) together with an abelian group \((G, +)\), and a new operator \(\cdot\) (i.e. scalar multiplication) such that:

  1. \(r \cdot (x + y) = r \cdot x + r \cdot y\)
  2. \((r + s) \cdot x = r \cdot x + s \cdot x\)
  3. \((rs) \cdot x = r \cdot (s \cdot x)\)
  4. \(1_R \cdot x = x\)

for all \(x, y\) in \(G\), and \(r, s\) in \(R\), where \(1_R\) is the identity of the ring.

A ring \(R, +, \cdot\) a set \(R\) with two operators such that:

  1. \(R\) is an abelian group under \(+\)
  2. \(R\) is a monoid under \(\cdot\)
  3. \(cdot\) is _distributive_ with respect to \(+\). That is,
  4. (a cdot (b + c) = (a cdot b) + (a cdot c) (left distributivity)
  5. ((b + c) cdot a) = (b cdot a) + (c cdot a) (right distributivity)

Note we have to define left & right distributivity, because \(\cdot\) might not be commutative.

A monoid is a group without the notion of inverse. See Haskell's Monoid typeclass.

A \(\mathbb{Z}\)-module is a module where the ring \(R\) is the integers with normal addition and multiplication.

Associated Types

type Scalar group :: * Source #

A scalar for this group. Mathematically equivalent to an integer, but possibly stored differently for computational reasons.


scalarMultiply :: group -> Scalar group -> Element group -> Element group Source #

Multiply an element of the group with respect to a scalar.

This is equivalent to adding the element to itself N times, where N is a scalar. The default implementation does exactly that.

integerToScalar :: group -> Integer -> Scalar group Source #

Get the scalar that corresponds to an integer.

Note [Added for completeness]

\x -> scalarToInteger group (integerToScalar group x) == x

scalarToInteger :: group -> Scalar group -> Integer Source #

Get the integer that corresponds to a scalar.

Note [Added for completeness]

\x -> integerToScalar group (scalarToInteger group x) == x

scalarSizeBits :: group -> Int Source #

Size of scalars, in bits

generateElement :: MonadRandom randomly => group -> randomly (KeyPair group) Source #

Encode a scalar into bytes. | Generate a new random element of the group, with corresponding scalar.

class Group group where Source #

A mathematical group intended to be used with SPAKE2.

Associated Types

type Element group :: * Source #

An element of the group.


elementAdd :: group -> Element group -> Element group -> Element group Source #

Group addition.

\x y z -> elementAdd group (elementAdd group x y) z == elementAdd group x (elementAdd group y z)

elementNegate :: group -> Element group -> Element group Source #

Inverse with respect to group addition.

\x -> (elementAdd group x (elementNegate group x)) == groupIdentity
\x -> (elementNegate group (elementNegate group x)) == x

elementSubtract :: group -> Element group -> Element group -> Element group Source #

Subtract one element from another.

\x y -> (elementSubtract group x y) == (elementAdd group x (elementNegate group y))

groupIdentity :: group -> Element group Source #

Identity of the group.

Note [Added for completeness]

\x -> (elementAdd group x groupIdentity) == x
\x -> (elementAdd group groupIdentity x) == x

encodeElement :: ByteArray bytes => group -> Element group -> bytes Source #

Encode an element of the group into bytes.

Note [Byte encoding in Group]

\x -> decodeElement group (encodeElement group x) == CryptoPassed x

decodeElement :: ByteArray bytes => group -> bytes -> CryptoFailable (Element group) Source #

Decode an element into the group from some bytes.

Note [Byte encoding in Group]

elementSizeBits :: group -> Int Source #

Size of elements, in bits

arbitraryElement :: ByteArrayAccess bytes => group -> bytes -> Element group Source #

Deterministically create an arbitrary element from a seed bytestring.

XXX: jml would much rather this take a scalar, an element, or even an integer, rather than bytes because bytes mean that the group instances have to know about hash algorithms and HKDF. If the IntegerGroup class in SPAKE2 also oversized its input, then it and the ed25519 implementation would have identical decoding.


decodeScalar :: (ByteArrayAccess bytes, AbelianGroup group) => group -> bytes -> Scalar group Source #

Map some arbitrary bytes into a scalar in a group.

elementSizeBytes :: Group group => group -> Int Source #

Size of elements in a group, in bits.

scalarSizeBytes :: AbelianGroup group => group -> Int Source #

Size of scalars in a group, in bytes.

data KeyPair group Source #

A group key pair composed of the private part (a scalar) and a public part (associated group element).