Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatting changes and spelling errors corrected #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 28 additions & 23 deletions Lab01Basics/Lab01Code.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ def encrypt_message(K, message):

plaintext = message.encode("utf8")

## YOUR CODE HERE
## ADD CODE HERE

return (iv, ciphertext, tag)

def decrypt_message(K, iv, ciphertext, tag):
""" Decrypt a cipher text under a key K

In case the decryption fails, throw an exception.
"""
Decrypt a cipher text under a key K
In case the decryption fails, throw an exception.
"""
## YOUR CODE HERE
## ADD CODE HERE

return plain.encode("utf8")

Expand All @@ -56,7 +56,7 @@ def decrypt_message(K, iv, ciphertext, tag):
# - Implement Scalar multiplication (double & add).
# - Implement Scalar multiplication (Montgomery ladder).
#
# MUST NOT USE ANY OF THE petlib.ec FUNCIONS. Only petlib.bn!
# MUST NOT USE ANY OF THE petlib.ec FUNCTIONS. Only petlib.bn!

from petlib.bn import Bn

Expand Down Expand Up @@ -89,7 +89,8 @@ def is_point_on_curve(a, b, p, x, y):


def point_add(a, b, p, x0, y0, x1, y1):
"""Define the "addition" operation for 2 EC Points.
"""
Define the "addition" operation for 2 EC Points.

Reminder: (xr, yr) = (xq, yq) + (xp, yp)
is defined as:
Expand All @@ -106,10 +107,11 @@ def point_add(a, b, p, x0, y0, x1, y1):
return (xr, yr)

def point_double(a, b, p, x, y):
"""Define "doubling" an EC point.
A special case, when a point needs to be added to itself.
"""
Define "doubling" an EC point.
A special case, when a point needs to be added to itself.

Reminder:
Reminder:
lam = (3 * xp ^ 2 + a) * (2 * yp) ^ -1 (mod p)
xr = lam ^ 2 - 2 * xp
yr = lam * (xp - xr) - yp (mod p)
Expand All @@ -134,13 +136,12 @@ def point_scalar_multiplication_double_and_add(a, b, p, x, y, scalar):
Q = Q + P
P = 2 * P
return Q

"""
Q = (None, None)
P = (x, y)

for i in range(scalar.num_bits()):
pass ## ADD YOUR CODE HERE
pass ## ADD CODE HERE

return Q

Expand All @@ -160,13 +161,12 @@ def point_scalar_multiplication_montgomerry_ladder(a, b, p, x, y, scalar):
R0 = R0 + R1
R1 = 2 R1
return R0

"""
R0 = (None, None)
R1 = (x, y)

for i in reversed(range(0,scalar.num_bits())):
pass ## ADD YOUR CODE HERE
pass ## ADD CODE HERE

return R0

Expand All @@ -184,8 +184,10 @@ def point_scalar_multiplication_montgomerry_ladder(a, b, p, x, y, scalar):
from petlib.ecdsa import do_ecdsa_sign, do_ecdsa_verify

def ecdsa_key_gen():
""" Returns an EC group, a random private key for signing
and the corresponding public key for verification"""
"""
Returns an EC group, a random private key for signing
and the corresponding public key for verification
"""
G = EcGroup()
priv_sign = G.order().random()
pub_verify = priv_sign * G.generator()
Expand All @@ -196,15 +198,15 @@ def ecdsa_sign(G, priv_sign, message):
""" Sign the SHA256 digest of the message using ECDSA and return a signature """
plaintext = message.encode("utf8")

## YOUR CODE HERE
## ADD CODE HERE

return sig

def ecdsa_verify(G, pub_verify, message, sig):
""" Verify the ECDSA signature on the message """
plaintext = message.encode("utf8")

## YOUR CODE HERE
## ADD CODE HERE

return res

Expand All @@ -225,23 +227,26 @@ def dh_get_key():


def dh_encrypt(pub, message, aliceSig = None):
""" Assume you know the public key of someone else (Bob),
"""
Assume you know the public key of someone else (Bob),
and wish to Encrypt a message for them.
- Generate a fresh DH key for this message.
- Derive a fresh shared key.
- Use the shared key to AES_GCM encrypt the message.
- Optionally: sign the message with Alice's key.
"""

## YOUR CODE HERE
## ADD CODE HERE
pass

def dh_decrypt(priv, ciphertext, aliceVer = None):
""" Decrypt a received message encrypted using your public key,
"""
Decrypt a received message encrypted using your public key,
of which the private key is provided. Optionally verify
the message came from Alice using her verification key."""
the message came from Alice using her verification key.
"""

## YOUR CODE HERE
## ADD CODE HERE
pass

## NOTE: populate those (or more) tests
Expand Down
1 change: 0 additions & 1 deletion Lab01Basics/Lab01Tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def test_gcm_fails():
def test_on_curve():
"""
Test the procedues that tests whether a point is on a curve.

"""

## Example on how to define a curve
Expand Down
4 changes: 2 additions & 2 deletions Lab01Basics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ $ py.test -v Lab01Tests.py -m task2

- The petlib.cipher package provides two handy functions `quick_gcm_enc` and `quick_gcm_dec` that will help you define the encryption and decryption functions.

- Use the encoded `plaintext` rather than the input directly (you can encypt bytes not unicode strings, hence the need for encoding and decoding with UTF8 first).
- Use the encoded `plaintext` rather than the input directly (you can encrypt bytes not unicode strings, hence the need for encoding and decoding with UTF8 first).

- The documentation for petlib.cipher is [available here](http://petlib.readthedocs.org/en/latest/index.html#module-petlib-cipher).

Expand Down Expand Up @@ -186,7 +186,7 @@ $ py.test -v Lab01Tests.py -m task5

- This task requires you to implement a simple hybrid encryption scheme, guided by the scheme presented in the slides. In a nutshell you may assume that Alice and Bob are aware of each other's public keys, and use those to eventually derive a shared key. This shared key is eventually used to key an AES-GCM cipher to protect the integrity and confidentiality of a message.

- You may assume that the public key passed to `dh_encrypt` is the public encryption key of the recipient, and the `aliceeSig` parameter is the signature key of Alice the sender. Conversely, the `priv` paramemter of `dh_encrypt` is the receipient's (Bob) secret decryption key and `aliceVer` a public verification key for a signature scheme.
- You may assume that the public key passed to `dh_encrypt` is the public encryption key of the recipient, and the `aliceeSig` parameter is the signature key of Alice the sender. Conversely, the `priv` parameter of `dh_encrypt` is the recipient's (Bob) secret decryption key and `aliceVer` a public verification key for a signature scheme.

- As part of this task you MUST implement a number of tests to ensure that your code is correct. Stubs for 3 such tests are provided, namely `test_encrypt`, `test_decrypt` (which are self explanatory), and `test_fails` which is meant to check for conditions under which the decryption must fail. At least these should be implemented in the code file, but feel free to implement more.

Expand Down
43 changes: 22 additions & 21 deletions Lab02Mix/Lab02Code.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from binascii import hexlify

def aes_ctr_enc_dec(key, iv, input):
""" A helper function that implements AES Counter (CTR) Mode encryption and decryption.
"""
A helper function that implements AES Counter (CTR) Mode encryption and decryption.
Expects a key (16 byte), and IV (16 bytes) and an input plaintext / ciphertext.

If it is not obvious convince yourself that CTR encryption and decryption are in
Expand Down Expand Up @@ -54,13 +55,13 @@ def aes_ctr_enc_dec(key, iv, input):
from petlib.cipher import Cipher

def mix_server_one_hop(private_key, message_list):
""" Implements the decoding for a simple one-hop mix.

Each message is decoded in turn:
- A shared key is derived from the message public key and the mix private_key.
- the hmac is checked against all encrypted parts of the message
- the address and message are decrypted, decoded and returned
"""
Implements the decoding for a simple one-hop mix.

Each message is decoded in turn:
- A shared key is derived from the message public key and the mix private_key.
- the hmac is checked against all encrypted parts of the message
- the address and message are decrypted, decoded and returned
"""
G = EcGroup()

Expand All @@ -69,14 +70,14 @@ def mix_server_one_hop(private_key, message_list):
# Process all messages
for msg in message_list:

## Check elements and lengths
# Check elements and lengths
if not G.check_point(msg.ec_public_key) or \
not len(msg.hmac) == 20 or \
not len(msg.address) == 258 or \
not len(msg.message) == 1002:
raise Exception("Malformed input message")

## First get a shared key
# First get a shared key
shared_element = private_key * msg.ec_public_key
key_material = sha512(shared_element.export()).digest()

Expand All @@ -85,7 +86,7 @@ def mix_server_one_hop(private_key, message_list):
address_key = key_material[16:32]
message_key = key_material[32:48]

## Check the HMAC
# Check the HMAC
h = Hmac(b"sha512", hmac_key)
h.update(msg.address)
h.update(msg.message)
Expand All @@ -94,7 +95,7 @@ def mix_server_one_hop(private_key, message_list):
if not secure_compare(msg.hmac, expected_mac[:20]):
raise Exception("HMAC check failure")

## Decrypt the address and the message
# Decrypt the address and the message
iv = b"\x00"*16

address_plaintext = aes_ctr_enc_dec(address_key, iv, msg.address)
Expand Down Expand Up @@ -128,7 +129,7 @@ def mix_client_one_hop(public_key, address, message):
address_plaintext = pack("!H256s", len(address), address)
message_plaintext = pack("!H1000s", len(message), message)

## Generate a fresh public key
# Generate a fresh public key
private_key = G.order().random()
client_public_key = private_key * G.generator()

Expand All @@ -153,7 +154,8 @@ def mix_client_one_hop(public_key, address, message):


def mix_server_n_hop(private_key, message_list, final=False):
""" Decodes a NHopMixMessage message and outputs either messages destined
"""
Decodes a NHopMixMessage message and outputs either messages destined
to the next mix or a list of tuples (address, message) (if final=True) to be
sent to their final recipients.

Expand All @@ -171,15 +173,15 @@ def mix_server_n_hop(private_key, message_list, final=False):
# Process all messages
for msg in message_list:

## Check elements and lengths
# Check elements and lengths
if not G.check_point(msg.ec_public_key) or \
not isinstance(msg.hmacs, list) or \
not len(msg.hmacs[0]) == 20 or \
not len(msg.address) == 258 or \
not len(msg.message) == 1002:
raise Exception("Malformed input message")

## First get a shared key
# First get a shared key
shared_element = private_key * msg.ec_public_key
key_material = sha512(shared_element.export()).digest()

Expand All @@ -192,7 +194,7 @@ def mix_server_n_hop(private_key, message_list, final=False):
blinding_factor = Bn.from_binary(key_material[48:])
new_ec_public_key = blinding_factor * msg.ec_public_key

## Check the HMAC
# Check the HMAC
h = Hmac(b"sha512", hmac_key)

for other_mac in msg.hmacs[1:]:
Expand All @@ -206,7 +208,7 @@ def mix_server_n_hop(private_key, message_list, final=False):
if not secure_compare(msg.hmacs[0], expected_mac[:20]):
raise Exception("HMAC check failure")

## Decrypt the hmacs, address and the message
# Decrypt the hmacs, address and the message
aes = Cipher("AES-128-CTR")

# Decrypt hmacs
Expand Down Expand Up @@ -245,7 +247,6 @@ def mix_client_n_hop(public_keys, address, message):
The maximum size of the final address and the message are 256 bytes and 1000 bytes respectively.
Returns an 'NHopMixMessage' with four parts: a public key, a list of hmacs (20 bytes each),
an address ciphertext (256 + 2 bytes) and a message ciphertext (1002 bytes).

"""
G = EcGroup()
# assert G.check_point(public_key)
Expand All @@ -257,7 +258,7 @@ def mix_client_n_hop(public_keys, address, message):
address_plaintext = pack("!H256s", len(address), address)
message_plaintext = pack("!H1000s", len(message), message)

## Generate a fresh public key
# Generate a fresh public key
private_key = G.order().random()
client_public_key = private_key * G.generator()

Expand All @@ -282,14 +283,14 @@ def generate_trace(number_of_users, threshold_size, number_of_rounds, targets_fr
all_users = range(number_of_users)

trace = []
## Generate traces in which Alice (user 0) is not sending
# Generate traces in which Alice (user 0) is not sending
for _ in range(number_of_rounds // 2):
senders = sorted(random.sample( others, threshold_size))
receivers = sorted(random.sample( all_users, threshold_size))

trace += [(senders, receivers)]

## Generate traces in which Alice (user 0) is sending
# Generate traces in which Alice (user 0) is sending
for _ in range(number_of_rounds // 2):
senders = sorted([0] + random.sample( others, threshold_size-1))
# Alice sends to a friend
Expand Down
2 changes: 1 addition & 1 deletion Lab02Mix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ where the `client_public_key` is an EC point, the expected Hmac is an Hmac of th

py.test -v Lab02Tests.py -m task3

- The key differences between the 1-hop mix and the n-hop mix message encoding relates to: (1) the use of a blinding factor to provide bit-wise unlikability of the public key associated with the message; (2) the inclusion of a sequence (list) of hmacs as the second part of the mix message; (3) the decryption of the hmacs (in addition to the address and message) at each step of mixing.
- The key differences between the 1-hop mix and the n-hop mix message encoding relates to: (1) the use of a blinding factor to provide bit-wise unlinkability of the public key associated with the message; (2) the inclusion of a sequence (list) of hmacs as the second part of the mix message; (3) the decryption of the hmacs (in addition to the address and message) at each step of mixing.

- The output of the function `mix_client_n_hop` should be an `NHopMixMessage`. The first element is a public key, the second is a list of hmacs, the third is the encrypted address and the final one is the encrypted message. You can build such a structure using:

Expand Down
Loading