Skip to content

Commit

Permalink
Fixed the C25519 bug. Thanks Hemi for the bug report!
Browse files Browse the repository at this point in the history
  • Loading branch information
gdanezis committed Jul 1, 2018
1 parent 03559b5 commit e5de1f3
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
81 changes: 76 additions & 5 deletions sphinxmix/SphinxClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,16 @@ def create_header(params, nodelist, keys, dest, assoc=None):
blind_factors = [ x ]
asbtuples = []

from binascii import hexlify

for k in keys:
alpha = group.expon_base(blind_factors)

s = group.expon(k, blind_factors)
aes_s = p.get_aes_key(s)
assert type(aes_s) == bytes

b = p.hb(aes_s)
# blind_factor = blind_factor.mod_mul(b, p.group.G.order())
blind_factors += [ b ]
blind_factors += [ b ]

hr = header_record(alpha, s, b, aes_s)
asbtuples.append(hr)
Expand Down Expand Up @@ -178,7 +179,7 @@ def create_header(params, nodelist, keys, dest, assoc=None):

# Compute the MAC over the associated data and beta
gamma = p.mu(p.hmu(asbtuples[nu-1].aes), assoc[nu-1] + beta)

for i in range(nu-2, -1, -1):
node_id = node_meta[i+1]

Expand All @@ -187,7 +188,7 @@ def create_header(params, nodelist, keys, dest, assoc=None):
plain = node_id + gamma + beta[:plain_beta_len]

beta = p.xor_rho(p.hrho(asbtuples[i].aes), plain)
gamma = p.mu(p.hmu(asbtuples[i].aes), assoc[i] + beta)
gamma = p.mu(p.hmu(asbtuples[i].aes), assoc[i] + beta)

return (asbtuples[0].alpha, beta, gamma), \
[x.aes for x in asbtuples]
Expand Down Expand Up @@ -347,6 +348,7 @@ def test_timing(rep=100, payload_size=1024 * 10):
def test_minimal():
from .SphinxParams import SphinxParams
r = 5

params = SphinxParams()

# The minimal PKI involves names of nodes and keys
Expand Down Expand Up @@ -532,6 +534,75 @@ def test_c25519(rep=100, payload_size=1024 * 10):

return T_package, T_process

def test_c25519_hemi(rep=1, payload_size=1024):
r = 5
from .SphinxParamsC25519 import Group_C25519

group = Group_C25519()
params = SphinxParams(group=group, body_len=payload_size, assoc_len=4)

# Monkey patch to use AES-CTR
params.lioness_enc = params.xor_rho
params.lioness_dec = params.xor_rho


pki = {}

pkiPriv = {}
pkiPub = {}

for i in range(10):
nid = pack("b", i) # Nenc(params, bytes([i]))
x = params.group.gensecret()
y = crypto_scalarmult_base(x)
pkiPriv[nid] = pki_entry(nid, x, y)
pkiPub[nid] = pki_entry(nid, None, y)


# The simplest path selection algorithm and message packaging
use_nodes = rand_subset(pkiPub.keys(), r)
nodes_routing = list(map(Nenc, use_nodes))
node_keys = [pkiPub[n].y for n in use_nodes]

assoc = [b"XXXX"] * len(nodes_routing)

header, delta = create_forward_message(params, nodes_routing, node_keys, b"dest", b"this is a test", assoc)


from .SphinxNode import sphinx_process
from binascii import hexlify

x = pkiPriv[use_nodes[0]].x
i = 0
while True:
assert pkiPriv[use_nodes[i]].x == x
assert pkiPriv[use_nodes[i]].y == node_keys[i]

alpha, beta, gamma = header

(_, B, (header, delta), mac_key) = sphinx_process(params, x, header, delta, b"XXXX")

routing = PFdecode(params, B)
assert i == 4 or B == nodes_routing[i+1]

i += 1

if routing[0] == Relay_flag:
addr = routing[1]
assert addr == use_nodes[i]
x = pkiPriv[addr].x
elif routing[0] == Dest_flag:
assert len(routing) == 1
dec_dest, dec_msg = receive_forward(params, mac_key, delta)
assert dec_dest == b"dest"
assert dec_msg == b"this is a test"

break
else:
print("Error")
assert False
break




Expand Down
9 changes: 7 additions & 2 deletions sphinxmix/SphinxNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ def sphinx_process(params, secret, header, delta, assoc=b''):
aes_s = p.get_aes_key(s)

assert len(beta) == p.max_len - 32
if gamma != p.mu(p.hmu(aes_s), assoc + beta):

newgamma = p.mu(p.hmu(aes_s), assoc + beta)
if gamma != newgamma:
raise SphinxException("MAC mismatch.")

beta_pad = beta + (b"\x00" * (2 * p.max_len))
Expand All @@ -60,7 +62,10 @@ def sphinx_process(params, secret, header, delta, assoc=b''):

tag = p.htau(aes_s)
b = p.hb(aes_s)
alpha = group.expon(alpha, [ b ])

alpha_new = group.expon(alpha, [ b ])
alpha = alpha_new

gamma = rest[:p.k]
beta = rest[p.k:p.k+(p.max_len - 32)]
delta = p.pii(p.hpi(aes_s), delta)
Expand Down
22 changes: 18 additions & 4 deletions sphinxmix/SphinxParamsC25519.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@

from nacl.bindings import crypto_scalarmult_base, crypto_scalarmult

def _expand32(K):
return (K+b"\x00"*32)[:32]

class Group_C25519:
"Group operations using Curve 25519"

Expand All @@ -47,13 +50,14 @@ def gensecret(self):

def expon(self, base, exp):
for f in exp:
base = crypto_scalarmult(f, base)
base = crypto_scalarmult(_expand32(f), base)
return base

def expon_base(self, exp):
base = crypto_scalarmult_base(exp[0])
assert len(exp) > 0
base = crypto_scalarmult_base(_expand32(exp[0]))
for f in exp[1:]:
base = crypto_scalarmult(f, base)
base = crypto_scalarmult(_expand32(f), base)
return base


Expand All @@ -65,4 +69,14 @@ def in_group(self, alpha):
return len(alpha) == 32

def printable(self, alpha):
return alpha
return alpha

def test_commut():
G = Group_C25519()
x0, x1, x2 = [G.gensecret() for _ in range(3) ]
x2 = x2[:16]

assert G.expon_base([x0, x1, x2]) == G.expon_base([x2, x1, x0])

assert G.expon_base([x0, x1, x2]) == G.expon( G.expon_base([x0, x1]), [ x2 ])
assert G.expon_base([x0, x2]) == G.expon( G.expon_base([x0]), [ x2 ])

0 comments on commit e5de1f3

Please sign in to comment.