Copy some functions over from the signal docs
This commit is contained in:
@@ -54,6 +54,8 @@ print("Testing Reporting")
|
|||||||
content = "inappropriate message contents"
|
content = "inappropriate message contents"
|
||||||
reportPT, reportCT = alice.report("Bob", content)
|
reportPT, reportCT = alice.report("Bob", content)
|
||||||
decryptedReport = server.decryptReport(reportCT)
|
decryptedReport = server.decryptReport(reportCT)
|
||||||
|
print(reportPT)
|
||||||
|
print(decryptedReport)
|
||||||
if decryptedReport != reportPT:
|
if decryptedReport != reportPT:
|
||||||
error("report did not decrypt properly")
|
error("report did not decrypt properly")
|
||||||
print(reportPT)
|
print(reportPT)
|
||||||
|
|||||||
@@ -49,6 +49,80 @@ class MessengerClient:
|
|||||||
self.dh = GENERATE_DH()
|
self.dh = GENERATE_DH()
|
||||||
self.certificate = None
|
self.certificate = None
|
||||||
|
|
||||||
|
def RatchetInitAlice(state, SK, bob_dh_public_key):
|
||||||
|
state.DHs = GENERATE_DH()
|
||||||
|
state.DHr = bob_dh_public_key
|
||||||
|
state.RK, state.CKs = KDF_RK(SK, DH(state.DHs, state.DHr))
|
||||||
|
state.CKr = None
|
||||||
|
state.Ns = 0
|
||||||
|
state.Nr = 0
|
||||||
|
state.PN = 0
|
||||||
|
state.MKSKIPPED = {}
|
||||||
|
|
||||||
|
def RatchetInitBob(state, SK, bob_dh_key_pair):
|
||||||
|
state.DHs = bob_dh_key_pair
|
||||||
|
state.DHr = None
|
||||||
|
state.RK = SK
|
||||||
|
state.CKs = None
|
||||||
|
state.CKr = None
|
||||||
|
state.Ns = 0
|
||||||
|
state.Nr = 0
|
||||||
|
state.PN = 0
|
||||||
|
state.MKSKIPPED = {}
|
||||||
|
|
||||||
|
def RatchetSendKey(state):
|
||||||
|
state.CKs, mk = KDF_CK(state.CKs)
|
||||||
|
Ns = state.Ns
|
||||||
|
state.Ns += 1
|
||||||
|
return Ns, mk
|
||||||
|
|
||||||
|
def RatchetEncrypt(state, plaintext, AD):
|
||||||
|
Ns, mk = RatchetSendKey(state)
|
||||||
|
header = HEADER(state.DHs, state.PN, Ns)
|
||||||
|
return header, ENCRYPT(mk, plaintext, CONCAT(AD, header))
|
||||||
|
|
||||||
|
def RatchetReceiveKey(state, header):
|
||||||
|
mk = TrySkippedMessageKeys(state, header)
|
||||||
|
if mk != None:
|
||||||
|
return mk
|
||||||
|
if header.dh != state.DHr:
|
||||||
|
SkipMessageKeys(state, header.pn)
|
||||||
|
DHRatchet(state, header)
|
||||||
|
SkipMessageKeys(state, header.n)
|
||||||
|
state.CKr, mk = KDF_CK(state.CKr)
|
||||||
|
state.Nr += 1
|
||||||
|
return mk
|
||||||
|
|
||||||
|
def RatchetDecrypt(state, header, ciphertext, AD):
|
||||||
|
mk = RatchetReceiveKey(state, header)
|
||||||
|
return DECRYPT(mk, ciphertext, CONCAT(AD, header))
|
||||||
|
|
||||||
|
def TrySkippedMessageKeys(state, header):
|
||||||
|
if (header.dh, header.n) in state.MKSKIPPED:
|
||||||
|
mk = state.MKSKIPPED[header.dh, header.n]
|
||||||
|
del state.MKSKIPPED[header.dh, header.n]
|
||||||
|
return mk
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def SkipMessageKeys(state, until):
|
||||||
|
if state.Nr + MAX_SKIP < until:
|
||||||
|
raise Error()
|
||||||
|
if state.CKr != None:
|
||||||
|
while state.Nr < until:
|
||||||
|
state.CKr, mk = KDF_CK(state.CKr)
|
||||||
|
state.MKSKIPPED[state.DHr, state.Nr] = mk
|
||||||
|
state.Nr += 1
|
||||||
|
|
||||||
|
def DHRatchet(state, header):
|
||||||
|
state.PN = state.Ns
|
||||||
|
state.Ns = 0
|
||||||
|
state.Nr = 0
|
||||||
|
state.DHr = header.dh
|
||||||
|
state.RK, state.CKr = KDF_RK(state.RK, DH(state.DHs, state.DHr))
|
||||||
|
state.DHs = GENERATE_DH()
|
||||||
|
state.RK, state.CKs = KDF_RK(state.RK, DH(state.DHs, state.DHr))
|
||||||
|
|
||||||
def generateCertificate(self):
|
def generateCertificate(self):
|
||||||
self.certificate = pickle.dumps((self.name, self.dh.public_key().public_bytes(serialization.Encoding.X962,
|
self.certificate = pickle.dumps((self.name, self.dh.public_key().public_bytes(serialization.Encoding.X962,
|
||||||
serialization.PublicFormat.UncompressedPoint)))
|
serialization.PublicFormat.UncompressedPoint)))
|
||||||
|
|||||||
Reference in New Issue
Block a user