1S      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR,Miscellany. Mostly to do with serialization.NoneTake 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 .!Interface for mathematical groupsNoneDRgA group key pair composed of the private part (a scalar) and a public part (associated group element). 5A mathematical group intended to be used with SPAKE2.Notes:gThis is a much richer interface than one would expect from a group purely derived from abstract algebradjml thinks this is relevant to all Diffie-Hellman cryptography, but too ignorant to say for sureOIs this group automatically abelian? cyclic? Must it have these properties? An element of the group. ~A scalar for this group. Mathematically equivalent to an integer, but possibly stored differently for computational reasons. 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:Multiply an element of the group with respect to a scalar.PThis is equivalent to adding the element to itself N times, where N is a scalar..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) == 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]eEncode a scalar into bytes. | Generate a new random element of the group, with corresponding scalar.Size of elements, in bitsSize of scalars, 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.      Ed25519 group for SPAKE2None !#,DR_SHA point that might be a member of Ed25519. Note: [Extended coordinates]T8Whether or not an extended point is a member of Ed25519.U'Errors that can occur within the group.V.Translate internal errors into CryptoFailable.W0Guarantee an element is in the Ed25519 subgroup.X/Assert that an element is the Ed25519 subgroup.Panics if it is not.Y&The order of the group represented by .>Note that this is a subgroup of the underlying elliptic curve.Z0The generator for the (sub)group represented by .[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]_Add 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-3`Double an extended point. dbl-2008-hwcda@Multiply a point (might be in the group, might not) by a scalar.b/Scalar multiplication parametrised by addition.c5Attempt to create a member of Ed25519 from an affine y coordinate.d0Construct an affine point that is on Curve25519.e Encode an f 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.-fghiSjklmnTopUqrsVWX\YtuZ[v]^_`abcdewxyz{|}YZfghiSjklmnTopUqrsVWX\YtuZ[v]^_`abcdewxyz{|}"Additive group of integers modulo nNoneDRSimple integer addition group.Do NOT% use this for anything cryptographic. ~  ~(Multiplicative group of integers modulo nNone#DR!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.'1024 bit integer group.Originally from  /http://haofeng66.googlepages.com/JPAKEDemo.java, via  'https://github.com/warner/python-spake2 python-spake2.!"#$%&'!"%#$&'!"#$%&'-Implementation of various mathematical groupsNone  !"%#$&' !"#$%&' *The mathematical implementation of SPAKE2.None#: (*A SPAKE2 exchange that has been initiated.Description of the specific instance of the SPAKE2 protocol we are using. Parameters, password, and group must be the same for this to work.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 0 and 1./)The cyclic group used for encrypting keys0EThe "blind" we use when sending out values. Side A refers to this as M in the protocol description.1NThe "blind" the other side uses when sending values. Side A refers to this as N in the protocol description.22Initiate the SPAKE2 exchange. Generates a secret (xyW) that will be held by this side, and transmitted to the other side in "blinded" form.3Determine the element (either  X^{\star} or  Y^{\star}) to send to the other side.4Generate 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)()*+,-./01234An 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. ()*+,-./01234 )*+,-./012(34()*+,-./01234.Implementation of SPAKE2 key exchange protocolNone#5,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 C or D.The group to use for encryption2Hash algorithm used for generating the session key&How the two sides relate to each otherhRelation between two sides in SPAKE2. Can be either symmetric (both sides are the same), or asymmetric.1XXX: Maybe too generic? Could reasonably replace a with 'Side group'./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 areDescription used by both sides.6Which 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.9TAn 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.:*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 ?.>Do-nothing function so that we have something to import in our tests. TODO: Actually test something genuine and then remove this.?Construct a password.:Convert a user-supplied password into a scalar on a group.FExpand a password using HKDF so that it has a certain number of bytes.:TODO: jml cannot remember why you might want to call this.@>Turn an element into a message from this side of the protocol.ATurn a 9 into human-readable text.B9Extract an element on the group from an incoming message. Returns a 9c 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.C(Construct an asymmetric SPAKE2 protocol.D&Construct a symmetric SPAKE2 protocol.WGet the parameters for the mathematical part of SPAKE2 from the protocol specification.ECommence a SPAKE2 exchange.F3Create 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.)56789:;<=>?@ABCDEF#The protocol used for this exchangeThe message from side A,  X^{\star}, or either side if symmetricThe message from side B,  Y^{\star}, or either side if symmetricThe calculated key material, KThe shared secret password.A session key to use for further communication3456789:;<=>?@ABCDEF>=?5CDE34B9A@F:;<67856789:;<=>?@ABCDEF    !"#$%&&''())*+,-./001233456789:;<=>??@ABCDEFGH7IJKLMNOPQRSTUVWXYZ[\,]^_`abcdefghhijVklmnopqrstuvwxyz{|}~4  :A#spake2-0.1.0-8PwFn5jpdEYDFrNZOQS9DLCrypto.Spake2.UtilCrypto.Spake2.GroupCrypto.Spake2.GroupsCrypto.Spake2.Math Crypto.Spake2Crypto.Spake2.Groups.Ed25519$Crypto.Spake2.Groups.IntegerAddition!Crypto.Spake2.Groups.IntegerGroupRelationus expandDataexpandArbitraryElementSeed numberToBytesunsafeNumberToBytes bytesToNumberKeyPair keyPairPublickeyPairPrivateGroupElementScalar elementAdd elementNegateelementSubtract groupIdentityscalarMultiplyintegerToScalarscalarToInteger encodeElement decodeElementgenerateElementelementSizeBitsscalarSizeBitsarbitraryElement decodeScalarelementSizeBytesscalarSizeBytesEd25519IntegerAdditionmodulus IntegerGrouporder subgroupOrder generatormakeIntegerGroupi1024Spake2ExchangeSpake2paramspasswordParamsgroupourBlind theirBlind startSpake2computeOutboundMessagegenerateKeyMaterialProtocol WhichSideSideASideB MessageErrorSideIDunSideIDPassword something makePasswordelementToMessage formatErrorextractElementmakeAsymmetricProtocolmakeSymmetricProtocolcreateSessionKey $fEqPassword $fOrdPassword $fEqSideID $fOrdSideID $fShowSideID$fEqMessageError$fShowMessageError $fEqWhichSide$fOrdWhichSide$fShowWhichSide$fBoundedWhichSide$fEnumWhichSide ExtendedPointGroupMembershipErrortoCryptoFailable ensureInGroup assertInGrouplinvq extendedZeroisExtendedZeroaddExtendedPointsdoubleExtendedPointsafeScalarMultiplyscalarMultiplyExtendedPointmakeGroupMembermakeAffinePointencodeAffinePoint AffinePoint$sel:x:AffinePoint$sel:y:AffinePoint$sel:x:ExtendedPoint$sel:y:ExtendedPoint$sel:z:ExtendedPoint$sel:t:ExtendedPointUnknownMember NotOnCurve NotInGroup LowOrderPointdConstixRecoverdecodeAffinePointnumberToLitteEndianByteslittleEndianBytesToNumberaffineToExtendedextendedToAffine'$fEqExtendedPoint$fGroupEd25519$fGroupIntegerAddition$fGroupIntegerGroupspake2xyStarted hashAlgorithmrelationsideAsideB bothSidesSidesideIDblind EmptyMessageUnexpectedPrefix BadCryptopasswordToScalarexpandPassword getParams Asymmetric Symmetric theirPrefix