MpOTR/algorithm dump
Contents
Example of an Algorithm in Wiki
Procedure LargestNumber Input: A list of numbers L. Output: The largest number in the list L.
largest ← null
for each item in "L"', do
if item > largest, then
largest ← item
return largest
mpOTR algorithms
Chatroom setup
Procedure Chat Initiator Init
Input: newRoomName, participantNick
Global myId := 1
Global Nick_{myId} := participantNick
Global roomName := newRoomName
Global x_{myId}, y_{myId} := Call Generate Initial Paramters(myId)
Global signatureKey_{myId} := (x_{myId},y_{myId})
participantList := [Nick_{myId}]
ephemeralPublicPointList := [y_{myId}, y_{other}]
Procedure Verify Verifier Generate Init Key
Input: schnorrRandomPoint_{other
Call Verify Verifiers()
Global sessionKey := SHA-512(x_{myId}y_{other}, sessionId)
toBeSigned := SHA-512(SHA-512(sessionId||SHA-512(y_1, v_1)||SHA-512(y_2,v_2)))
Call Sign Session and Send(toBeSigned)
Join
Procedure Join
Input: newRoomName, Nickname_{myId
Global myId := participantId
Global roomName := newRoomName
x_{myId}, y_{myId} := Call Generate Initial Paramters(Participant ID myId)
Global signatureKey_{myId} := (x_{myId},y_{myId})
Call Broadcast(``:3mpCat:3Join:3, myId, Nickname_{myId)
Global participantList, ephemeralPublicPointList := Call Receive()
Global sessionId := Call Compute Session Id(roomName, participantList, ephemeralPublicPointList)
Call Sign and Send Key Confirmation and Shares()
Call Wait On Receive(``:3mpCat:3KeyConfirmationShare:3)
Global keyShareList, keyConfirmationList, signatureList := Call Receive()
Call Verify Key Confirmations and Signatures(keyConfirmationList, signatureList)
Call Update Session Key()
Procedure Receive Session Digest Input: currentSessionHistoryDigest Global sessionDigest := currentSessionHistoryDigest
Protocol for other participants already in the chat to accept the newcomer
Procedure Accept
Input: newParticipant
Call Broadcast(``:3mpCat:3Join:3, myId, Nickname_{myId)
Call Wait On Receive(``:3mpCat:3Join:3)
Global nick_{NewParticipant}, ephemeralPublicPoint_{NewParticipant} := Call Receive()
Call Update Lists(nick_{NewParticipant)
Global sessionId := Call Compute Session Id(roomName, participantList, ephemeralPublicPointList)
Call Sign and Send Key Confirmation and Shares()
Call Wait On Receive(``:3mpCat:3KeyConfirmationShare:3)
Global keyShareList, keyConfirmationList, signatureList := Call Receive()
Call Verify Key Confirmations and Signatures(keyConfirmationList, signatureList)
Call Update Session Key()
Call Send(sessionDigest)
Farewell
Procedure Shrink on Leave
Input: leaverId
Remove leaverId from participantIdList
Global sessionId := Call Compute Session Id()
\If{|participantList| > 1}
Call Sign and Send Key Shares()
Call Wait On Receive(``:3mpCat:3KeyShare:3)
keyShareList := Receive{}
Call Update Session Key(keyShareList)
Procedure Sign and Send Key Shares
Input:
Global z_{myId -1, myId} := SHA-512(k_{myId,myId-1}, sessionId)
Global z_{myId, myId+1} := SHA-512(k_{myId,myId+1}, sessionId)
keyShare_{myId} := z_{myId -1, myId} \oplus z_{myId, myId+1}
originAuthSignature := Call ED25519Sign(SignatureKey, sessionId || z_{myId)
Call Broadcast(``:3mpCat:3KeyShare:3, myId, keyShare_{myId)
Send
Procedure Send Input: Message keyShareMessage = Call NewKeyShareMessage(MetaMessage) cryptMessage := Call AES CTR Encrypt(sessionKey,message | keyShareMessage) originAuthSignature := Call ED25519Sign(SignatureKey, sessionId || cryptMetatMessage) sessionDigest := Call Compute Session Digest(lastMessage) Call Broadcast(``:3mpCat:3, sessionId, cryptMessage, sessionDigest, originAuthSignature,``:3)
Recieve
Procedure Receive
Input: sender, encryptedMessage, originAuthSignature, sessionDigest
v := Call ED25519VerifySignature(ephemeralPublicKeyList[Sender], sessionId || encryptedMessage, originAuthSignature)
Call Assert(v)
message, keyShareMessage := Call AES CTR Decrypt(sessionKey, encryptedMessage)
isMetaMessage = Call UpdateNewKeyStatus(keyShareMessage)
Call Verify Digests(sessionDiges)
Return{isMetaMessage, message}
\subsection{Common functions}
Common functions used by other procedures in different stages
Procedure Generate Initial Paramters
Input: myId
signaturePrivateKey := Call RandomBits(256)
x_{myId} := Call Ed25519 Scalar(signaturePrivateKey))
y_{myId} := x_{myId}P
Return x,y
Procedure Verify Key Confirmation and Signatures
Input: signatureList, keyConfirmationList
For each participant \in participantList}, do
\If{keyConfirmationList[participant][myId] \neq SHA-512(k_{myId,participant}, U_{myId})}
Call Halt()
' \If{Call ED25519VerifySignature(ephemeralPublicKeyList[particicpant], sessionId ||keyShares[myId], originAuthSignature)'
Call Halt()
Procedure Compute Session Id Input: participantList, ephemeralPublicPointList Return SHA-512(roomeName, zip(participantList, ephemeralPublicPointList)) # zip([a,b],[c,d]):=[(a,c),(b,d)]
Procedure Verify Signatures Input: longPublicList,schnorrRandomPointList,
Procedure Sign and Send Key Confirmation and Share
Input: schnorrRandomPointList
For each participant \in participantList, do
k_{myId, participant} := H(g^{lp_{myId}}LP_{participant}y_{participant}^{x_{myId}}) # Triple DH
kc_{myId} := kc_{myId} | H(k_{myId,participant}, U_{participant})
Global z_{myId -1, myId} := SHA-512(k_{myId,myId-1}, sessionId)
Global z_{myId, myId+1} := SHA-512(k_{myId,myId+1}, sessionId)
keyShare_{myId} := z_{myId -1, myId} \oplus z_{myId, myId+1}
originAuthSignature := Call ED25519Sign(SignatureKey, sessionId || z_{myId)
Call Broadcast(``:3mpCat:3KeyConfirmationAndShare:3, myId, keyShare_{myId)
Procedure Update Session Key Input: keyShareList i := myId
For each {j \in [i,...,i+n-1]}}, do
z_{j,j+1} := z_{j-1,j} \oplus keyShareListe[j+1]
# recovered z_{i-1,i} should be equal to its original value
Global sessionKey := SHA-512(z_{j,j+1} | j \in [1...n])
Procedure Sign Params Update Session Key
Input: toBeSigned, signatureList, keyShareList
Call Update Session Key()
toBeSigned := SHA-512(sessionId, ||SHA-512(verifierList, ephemeralPublicPointList, keyShareList)))
signature_{myId} := Call Sign Session and Send(toBeSigned)
Call Broadcast(``:3mpCat:3SignedSessionParameters:3,signature_{myId)
Procedure ComputeSessionDigest Input: lastMessage
For each message in Messages Received from lastDigestedMessage+1 till lastMessage}, do
sesionDigest := Call SHA-512(sessionDigest, message) Call LRU Cache Store Digest(sessionDigest, message) Return sessionDigest,lastMessageId