úÎ#ä@ÜòQ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP,Miscellany. Mostly to do with serialization.NoneÂspake2›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.spake21Given a seed value for an arbitrary element (see arbitraryElement(), expand it to be of the given length.spake24Serialize a number according to the SPAKE2 protocol.ZJust kidding, there isn't a SPAKE2 protocol. This just matches the Python implementation. Inverse of .spake24Serialize a number according to the SPAKE2 protocol.FPanics if the number is too big to fit into the given number of bytes.spake26Deserialize 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 groupsNoneHVIospake2gA group key pair composed of the private part (a scalar) and a public part (associated group element). spake2A 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. spake2~A scalar for this group. Mathematically equivalent to an integer, but possibly stored differently for computational reasons. spake2: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. spake2.Get the scalar that corresponds to an integer.Note [Added for completeness]:\x -> scalarToInteger group (integerToScalar group x) == x spake2-Get the integer that corresponds to a scalar.Note [Added for completeness]:\x -> integerToScalar group (scalarToInteger group x) == xspake2Size of scalars, in bitsspake2eEncode a scalar into bytes. | Generate a new random element of the group, with corresponding scalar.spake25A mathematical group intended to be used with SPAKE2.spake2An element of the group.spake2Group addition.`\x y z -> elementAdd group (elementAdd group x y) z == elementAdd group x (elementAdd group y z)spake2'Inverse with respect to group addition.C\x -> (elementAdd group x (elementNegate group x)) == groupIdentity8\x -> (elementNegate group (elementNegate group x)) == xspake2"Subtract one element from another.S\x y -> (elementSubtract group x y) == (elementAdd group x (elementNegate group y))spake2Identity of the group.Note [Added for completeness]-\x -> (elementAdd group x groupIdentity) == x-\x -> (elementAdd group groupIdentity x) == xspake2*Encode an element of the group into bytes.Note [Byte encoding in Group]C\x -> decodeElement group (encodeElement group x) == CryptoPassed xspake21Decode an element into the group from some bytes.Note [Byte encoding in Group]spake2Size of elements, in bitsspake2EDeterministically 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.spake22Map some arbitrary bytes into a scalar in a group.spake2%Size of elements in a group, in bits.spake2%Size of scalars in a group, in bytes.  *The mathematical implementation of SPAKE2.None$>hØ spake2*A SPAKE2 exchange that has been initiated.Rspake2Description of the specific instance of the SPAKE2 protocol we are using. Parameters, password, and group must be the same for this to work.Sspake2œ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.spake2MAn instance of the SPAKE2 protocol. This represents one side of the protocol."spake2vThe parameters of the SPAKE2 protocol. The other side needs to be using the same values, but with swapped values for % and &.$spake2)The cyclic group used for encrypting keys%spake2EThe "blind" we use when sending out values. Side A refers to this as M in the protocol description.&spake2NThe "blind" the other side uses when sending values. Side A refers to this as N in the protocol description.'spake22Initiate the SPAKE2 exchange. Generates a secret (xyW) that will be held by this side, and transmitted to the other side in "blinded" form.(spake2Determine the element (either  X^{\star} or  Y^{\star}) to send to the other side.)spake2Generate 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))spake2An initiated SPAKE2 exchangespake2=The outbound message from the other side (i.e. inbound to us)spake2<The final piece of key material to generate the session key.  !"#$%&'()  !"#$%&'()(Multiplicative group of integers modulo nNone$HVql*spake2QA finite group of integers with respect to multiplication modulo the group order.Construct with /./spake2 Construct an *.qWill fail if generator is '1', since having the identity for a generator means the subgroup is the entire group..TODO: Find other things to check for validity.0spake21024 bit integer group.Originally from  /http://haofeng66.googlepages.com/JPAKEDemo.java, via  'https://github.com/warner/python-spake2 python-spake2.*+.,-/0Ed25519 group for SPAKE2None "$.HVdÖTspake2HA point that might be a member of Ed25519. Note: [Extended coordinates]Uspake28Whether or not an extended point is a member of Ed25519.Vspake2'Errors that can occur within the group.Wspake2.Translate internal errors into CryptoFailable.Xspake20Guarantee an element is in the Ed25519 subgroup.Yspake2/Assert that an element is the Ed25519 subgroup.Panics if it is not.Zspake2&The order of the group represented by 1.>Note that this is a subgroup of the underlying elliptic curve.[spake20The generator for the (sub)group represented by 1.\spake2Calculate 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^spake2&Zero in the extended coordinate space. RaffineZero = AffinePoint{x = 0, y = 1} extendedZero == affineToExtended affineZeroNote: [Extended coordinates]_spake2'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]`spake2Add 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-3aspake2Double an extended point. dbl-2008-hwcdbspake2Negate an extended point.cspake2@Multiply a point (might be in the group, might not) by a scalar.dspake2/Scalar multiplication parametrised by addition.espake25Attempt to create a member of Ed25519 from an affine y coordinate.fspake20Construct an affine point that is on Curve25519.gspake2 Encode an h 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.12Z[-Implementation of various mathematical groupsNoneŽÛ *+.,-/012 12*+.,-/0.Implementation of SPAKE2 key exchange protocolNone$Ûç3spake2,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.ispake2The group to use for encryptionjspake22Hash algorithm used for generating the session keykspake2&How the two sides relate to each otherlspake2hRelation between two sides in SPAKE2. Can be either symmetric (both sides are the same), or asymmetric.mspake2/Side A. Both sides need to agree who side A is.nspake2/Side B. Both sides need to agree who side B is.ospake2Which side we arepspake2Description used by both sides.4spake2Which side we are.qspake2 One side of the SPAKE2 protocol.rspake2Bytes identifying this sidesspake2VArbitrarily chosen element in the group used by this side to blind outgoing messages.7spake2TAn error that occurs when interpreting messages from the other side of the exchange.tspake2 We received an empty bytestring.uspake2EThe 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.vspake2‡Message could not be decoded to an element of the group. This can indicate either an error in serialization logic, or in mathematics.wspake2.An error arising from the "receive" action in B. Since 0.4.08spake2*Bytes that identify a side of the protocol;spake28Shared 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 <.<spake2Construct a password.xspake2:Convert a user-supplied password into a scalar on a group.=spake2>Turn an element into a message from this side of the protocol.>spake2Turn a 7 into human-readable text.?spake29Extract 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.@spake2(Construct an asymmetric SPAKE2 protocol.Aspake2&Construct a symmetric SPAKE2 protocol.yspake2WGet the parameters for the mathematical part of SPAKE2 from the protocol specification.Bspake2"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 z7. 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.Cspake2Commence a SPAKE2 exchange.Dspake23Create 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.Bspake2A 3j with all the parameters for the exchange. These parameters must be shared by both sides. Construct with @ or A.spake27The password shared between both sides. Construct with <.spake2!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.spake2$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.spake2aEither the shared session key or an error indicating we couldn't parse the other side's message.Dspake2#The protocol used for this exchangespake2)The outbound message, generated by this,  X^{\star}, or either side if symmetricspake22The inbound message, generated by the other side,  Y^{\star}, or either side if symmetricspake2The calculated key material, Kspake2The shared secret passwordspake2.A session key to use for further communication()3456789:;<=>?@ABCD;<3@ABC()?7>=D89:456 SafeÜÍ}~€‚ƒ„…    !"#$%&'(()*++,-./012234567889:;<=>>?@ABCDEFG/HIJKLMNOPQRSTUVWXYZ[\]^_`5abcdefghijklm,nopq rstuvwxyz{|}~U€‚ƒ „ … † ‡ ˆ ‰ Š ‹Œspake2-0.4.3-inplaceCrypto.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.BaseMonoidspake2xy ExtendedPointGroupMembershipErrortoCryptoFailable ensureInGroup assertInGrouplinvq extendedZeroisExtendedZeroaddExtendedPointsdoubleExtendedPointnegateExtendedPointsafeScalarMultiplyscalarMultiplyExtendedPointmakeGroupMembermakeAffinePointencodeAffinePoint AffinePoint hashAlgorithmrelationsideAsideB bothSidesSidesideIDblind EmptyMessageUnexpectedPrefix BadCrypto UnknownErrorpasswordToScalar getParamsLasync-2.2.2-26576412e696f3f5279bdd728fa2ed078bb8352ec41e484f5d10f218b3b5e3cbControl.Concurrent.Async concurrentlyGHC.MVarMVarbytestring-0.10.10.1Data.ByteString.Internal ByteStringversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName