úÎÜÓÅQ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP,Miscellany. Mostly to do with serialization.None>›Take an arbitrary sequence of bytes and expand it to be the given number of bytes. Do this by extracting a pseudo-random key and expanding it using HKDF.1Given a seed value for an arbitrary element (see arbitraryElement(), expand it to be of the given length.4Serialize a number according to the SPAKE2 protocol.ZJust kidding, there isn't a SPAKE2 protocol. This just matches the Python implementation. Inverse of .4Serialize a number according to the SPAKE2 protocol.FPanics if the number is too big to fit into the given number of bytes.6Deserialize a number according to the SPAKE2 protocol.ZJust kidding, there isn't a SPAKE2 protocol. This just matches the Python implementation. Inverse of ."Interfaces for mathematical groupsNoneFTFÈgA group key pair composed of the private part (a scalar) and a public part (associated group element). A group where  is commutative.That is, where4\x y -> elementAdd group x y == elementAdd group y x!This property leads to a natural  \mathbb{Z}G-module, where scalar multiplication is defined as repeatedly calling . DefinitionsWarning: 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: 'r \cdot (x + y) = r \cdot x + r \cdot y'(r + s) \cdot x = r \cdot x + s \cdot x"(rs) \cdot x = r \cdot (s \cdot x)1_R \cdot x = xfor 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: R is an abelian group under +R is a monoid under \cdotcdot# is _distributive_ with respect to + . That is,?(a cdot (b + c) = (a cdot b) + (a cdot c) (left distributivity)A((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 monoid9 is a group without the notion of inverse. See Haskell's Q typeclass.A  \mathbb{Z}#-module is a module where the ring R: is the integers with normal addition and multiplication. ~A scalar for this group. Mathematically equivalent to an integer, but possibly stored differently for computational reasons. :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. .Get the scalar that corresponds to an integer.Note [Added for completeness]:\x -> scalarToInteger group (integerToScalar group x) == x -Get the integer that corresponds to a scalar.Note [Added for completeness]:\x -> integerToScalar group (scalarToInteger group x) == xSize of scalars, in bitseEncode a scalar into bytes. | Generate a new random element of the group, with corresponding scalar.5A mathematical group intended to be used with SPAKE2.An element of the group.Group addition.`\x y z -> elementAdd group (elementAdd group x y) z == elementAdd group x (elementAdd group y z)'Inverse with respect to group addition.C\x -> (elementAdd group x (elementNegate group x)) == groupIdentity8\x -> (elementNegate group (elementNegate group x)) == x"Subtract one element from another.S\x y -> (elementSubtract group x y) == (elementAdd group x (elementNegate group y))Identity of the group.Note [Added for completeness]-\x -> (elementAdd group x groupIdentity) == x-\x -> (elementAdd group groupIdentity x) == x*Encode an element of the group into bytes.Note [Byte encoding in Group]C\x -> decodeElement group (encodeElement group x) == CryptoPassed x1Decode an element into the group from some bytes.Note [Byte encoding in Group]Size of elements, in bitsEDeterministically 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.2Map some arbitrary bytes into a scalar in a group.%Size of elements in a group, in bits.%Size of scalars in a group, in bytes.     *The mathematical implementation of SPAKE2.None$<e *A SPAKE2 exchange that has been initiated.RDescription of the specific instance of the SPAKE2 protocol we are using. Parameters, password, and group must be the same for this to work.S½Arbitrary element and scalar chosen by this side of the exchange. It is kept secret, and is only used to negotiate an exchange. A "blinded" form is sent to the other side of the protocol.MAn instance of the SPAKE2 protocol. This represents one side of the protocol."vThe parameters of the SPAKE2 protocol. The other side needs to be using the same values, but with swapped values for % and &.$)The cyclic group used for encrypting keys%EThe "blind" we use when sending out values. Side A refers to this as M in the protocol description.&NThe "blind" the other side uses when sending values. Side A refers to this as N in the protocol description.'2Initiate the SPAKE2 exchange. Generates a secret (xyW) that will be held by this side, and transmitted to the other side in "blinded" form.(Determine the element (either  X^{\star} or  Y^{\star}) to send to the other side.)Generate key material, K/, given a message from the other side (either  Y^{\star} or  X^{\star}).PThis key material is the last piece of input required to make the session key, SK, which should be generated as:2SK \leftarrow H(A, B, X^{\star}, Y^{\star}, K, pw)Where:H is a hash functionA identifies the initiating sideB identifies the receiving sideX^{star}1 is the outbound message from the initiating sideY^{star}0 is the outbound message from the receiving sideK is the result of this functionpw; is the password (this is what makes it SPAKE2, not SPAKE1))An initiated SPAKE2 exchange=The outbound message from the other side (i.e. inbound to us)<The final piece of key material to generate the session key.  !"#$%&'()  !"#$%&'()TRS !"#$%&(Multiplicative group of integers modulo nNone$FTmž*QA finite group of integers with respect to multiplication modulo the group order.Construct with /./ Construct an *.Will fail if generator is '1'T, since having the identity for a generator means the subgroup is the entire group..TODO: Find other things to check for validity.01024 bit integer group.Originally from  /http://haofeng66.googlepages.com/JPAKEDemo.java, via  'https://github.com/warner/python-spake2 python-spake2.*+.,-/0*+,-.Ed25519 group for SPAKE2None "$-FTaˆ,UHA point that might be a member of Ed25519. Note: [Extended coordinates]V8Whether or not an extended point is a member of Ed25519.W'Errors that can occur within the group.X.Translate internal errors into CryptoFailable.Y0Guarantee an element is in the Ed25519 subgroup.Z/Assert that an element is the Ed25519 subgroup.Panics if it is not.[&The order of the group represented by 1.>Note that this is a subgroup of the underlying elliptic curve.\0The generator for the (sub)group represented by 1.]Calculate the inverse of x modulo ^. Assumes that x is coprime with ^P and non-zero. Will raise an exception if either of these assumptions is false.\x -> (x * inv x) `mod` q == 1_&Zero in the extended coordinate space. RaffineZero = AffinePoint{x = 0, y = 1} extendedZero == affineToExtended affineZeroNote: [Extended coordinates]`'Check if a point is equivalent to zero.{jml is unsure, but this probably exists because it might be faster than mapping to affine space and checking for equality.Note: [Extended coordinates]aAdd two extended points.qThe points don't have to be in the Ed25519 subgroup, and we can't say anything about whether the result will be.add-2008-hwcd-3bDouble an extended point. dbl-2008-hwcdcNegate an extended point.d@Multiply a point (might be in the group, might not) by a scalar.e/Scalar multiplication parametrised by addition.f5Attempt to create a member of Ed25519 from an affine y coordinate.g0Construct an affine point that is on Curve25519.h Encode an i into bytes.$MSB of the output is whether or not x is even (i.e. x .&. 1,), teh rest of the output is little-endian y.12[\ijklUmnopqVrsWtuv12-Implementation of various mathematical groupsNone‰„ *+.,-/012 12*+,-./0.Implementation of SPAKE2 key exchange protocolNone$Ò;3,Everything required for the SPAKE2 protocol.FBoth sides must agree on these values for the protocol to work. This mostly" means value equality, except for  2, where each side must have complementary values.Construct with @ or A.wThe group to use for encryptionx2Hash algorithm used for generating the session keyy&How the two sides relate to each otherzhRelation between two sides in SPAKE2. Can be either symmetric (both sides are the same), or asymmetric.{/Side A. Both sides need to agree who side A is.|/Side B. Both sides need to agree who side B is.}Which side we are~Description used by both sides.4Which side we are. One side of the SPAKE2 protocol.€Bytes identifying this sideVArbitrarily chosen element in the group used by this side to blind outgoing messages.7TAn error that occurs when interpreting messages from the other side of the exchange.‚ We received an empty bytestring.ƒEThe bytestring had an unexpected prefix. We expect the prefix to be A if the other side is side A, B if they are side B, or SX if the connection is symmetric. First argument is received prefix, second is expected.„‡Message could not be decoded to an element of the group. This can indicate either an error in serialization logic, or in mathematics.….An error arising from the "receive" action in B. Since 0.4.08*Bytes that identify a side of the protocol;8Shared secret password used to negotiate the connection.7Constructor deliberately not exported, so that once a ;L has been created, the actual password cannot be retrieved by other modules.Construct with <.<Construct a password.†:Convert a user-supplied password into a scalar on a group.=>Turn an element into a message from this side of the protocol.>Turn a 7 into human-readable text.?9Extract an element on the group from an incoming message. Returns a 7c if we cannot decode the message, or the other side does not appear to be the expected other side.>TODO: Need to protect against reflection attack at some point.@(Construct an asymmetric SPAKE2 protocol.A&Construct a symmetric SPAKE2 protocol.‡WGet the parameters for the mathematical part of SPAKE2 from the protocol specification.B"Perform an entire SPAKE2 exchange.£Given a SPAKE2 protocol that has all of the parameters for this exchange, generate a one-off message from this side and receive a one off message from the other.OOnce we are done, return a key shared between both sides for a single session.SNote: as per the SPAKE2 definition, the session key is not guaranteed to actually workæ. If the other side has failed to authenticate, you will still get a session key. Therefore, you must exchange some other message that has been encrypted using this key in order to confirm that the session key is indeed shared.5Note: the "send" and "receive" actions are performed ˆ7. If you have ordering requirements, consider using a TVar or ‰8 to coordinate, or implementing your own equivalent of B.HIf the message received from the other side cannot be parsed, return a 7. Since 0.4.0.CCommence a SPAKE2 exchange.D3Create a session key based on the output of SPAKE2.2SK \leftarrow H(A, B, X^{\star}, Y^{\star}, K, pw) Including pw: in the session key is what makes this SPAKE2, not SPAKE1.Note!: In spake2 0.3 and earlier, The  X^{\star} and  Y^{\star}ÿD were expected to be from side A and side B respectively. Since spake2 0.4, they are the outbound and inbound elements respectively. This fixes an interoperability concern with the Python library, and reduces the burden on the caller. Apologies for the possibly breaking change to any users of older versions of spake2.BA 3j with all the parameters for the exchange. These parameters must be shared by both sides. Construct with @ or A.7The password shared between both sides. Construct with <.!An action to send a message. The Šz parameter is this side's SPAKE2 element, encoded using the group encoding, prefixed according to the parameters in the 3.$An action to receive a message. The Ši generated ought to be the protocol-prefixed, group-encoded version of the other side's SPAKE2 element.aEither the shared session key or an error indicating we couldn't parse the other side's message.D#The protocol used for this exchange)The outbound message, generated by this,  X^{\star}, or either side if symmetric2The inbound message, generated by the other side,  Y^{\star}, or either side if symmetricThe calculated key material, KThe shared secret password.A session key to use for further communication()3456789:;<=>?@ABCD;<3@ABC()?7>=D89:4563‹wxyzŒ{|}~456Ž€7‚ƒ„…89:; SafeÓž‘’“”•–—˜    !"#$%&'(()*++,-./012234567889:;<=>>?@ABCDEFG/HIJKLMNOPQRSTUVWXYZ[\]^_`a5bcdefghijklmnnop[qrstuvwxy,z{|} ~€‚ƒ„…†‡ˆ‰ŠU‹ŒŽ9‘@ ’ “ ” • – — ˜ ™š#spake2-0.4.2-LXYN02dwd5y5OhI926Xq3rCrypto.Spake2.UtilCrypto.Spake2.GroupCrypto.Spake2.MathCrypto.Spake2.Groups Crypto.Spake2!Crypto.Spake2.Groups.IntegerGroupCrypto.Spake2.Groups.Ed25519Relationus Paths_spake2 expandDataexpandArbitraryElementSeed numberToBytesunsafeNumberToBytes bytesToNumberKeyPair keyPairPublickeyPairPrivate AbelianGroupScalarscalarMultiplyintegerToScalarscalarToIntegerscalarSizeBitsgenerateElementGroupElement elementAdd elementNegateelementSubtract groupIdentity encodeElement decodeElementelementSizeBitsarbitraryElement decodeScalarelementSizeBytesscalarSizeBytesSpake2ExchangeSpake2paramspasswordParamsgroupourBlind theirBlind startSpake2computeOutboundMessagegenerateKeyMaterial IntegerGrouporder subgroupOrder generatormakeIntegerGroupi1024Ed25519Protocol WhichSideSideASideB MessageErrorSideIDunSideIDPassword makePasswordelementToMessage formatErrorextractElementmakeAsymmetricProtocolmakeSymmetricProtocolspake2ExchangecreateSessionKey $fEqPassword $fOrdPassword $fEqSideID $fOrdSideID $fShowSideID$fEqMessageError$fShowMessageError $fEqWhichSide$fOrdWhichSide$fShowWhichSide$fBoundedWhichSide$fEnumWhichSidebaseGHC.BaseMonoidspake2xyStarted ExtendedPointGroupMembershipErrortoCryptoFailable ensureInGroup assertInGrouplinvq extendedZeroisExtendedZeroaddExtendedPointsdoubleExtendedPointnegateExtendedPointsafeScalarMultiplyscalarMultiplyExtendedPointmakeGroupMembermakeAffinePointencodeAffinePoint AffinePoint$sel:x:AffinePoint$sel:y:AffinePoint$sel:x:ExtendedPoint$sel:y:ExtendedPoint$sel:z:ExtendedPoint$sel:t:ExtendedPointUnknownMember NotOnCurve NotInGroup LowOrderPoint hashAlgorithmrelationsideAsideB bothSidesSidesideIDblind EmptyMessageUnexpectedPrefix BadCrypto UnknownErrorpasswordToScalar getParams$async-2.1.1.1-H3j65XcXMHtBvmNwGCQ80GControl.Concurrent.Async concurrentlyGHC.MVarMVarbytestring-0.10.8.2Data.ByteString.Internal ByteString Asymmetric Symmetricversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName