edu.harvard.deas.hyperenc
Class HyperCollector

java.lang.Object
  extended by edu.harvard.deas.hyperenc.HyperCollector

public class HyperCollector
extends Object

Collects pages of random data, and stores pages, system blocks and encryption blocks for multiple contacts. Employs two HyperStorages for each contact: one to hold pages and blocks for outgoing communication to that contact, and one to hold pages and blocks for incoming communication from that contact.

A HyperCollector also implements methods for creating new reconciliation messages and processing incoming reconciliation messages, and for encrypting and decrypting messages.


Field Summary
static int BLOCK_LEN
          Length of a block, in bytes.
static int HASH_ENC
          the block to be used to encrypt the hash
static int NUM_SYSBLOCKS
          all the blocks necessary to make a new OTP
static int PAGE_LEN
          Length of a page, in bytes.
static int PAGE_SHUF
          the block to be used as the key to combine to pages into a OTP
static int PAGES_PER_PAD
          Number of pages that should be combined to form a single page of a one-time pad.
static int RS_SEED_INDEX
          the block to be used as the random seed for our random source
static int SYSBLOCKS_PER_PAD
          Number of system blocks to create each time a pad is created.
 
Constructor Summary
HyperCollector(Map<Contact,HyperStorage> masterstorages, Map<Contact,HyperStorage> slavestorages, Contact owner, HyperStorageFactory storageFactory)
          Constructs a new HyperCollector.
 
Method Summary
 void addHListener(HyperEncryptionListener listener)
          Register interest in HyperEncryptionEvents.
 void collectNext(Contact contact, Direction direction)
          Gets a page from a PSN, in the manner indicated by the system blocks.
 HyperMessage decrypt(HyperMessage encryptedMessage)
          Decrypt message.
 HyperMessage encrypt(HyperMessage unencrypted)
          Encrypts a message.
protected  void fireHEvent(Contact contact, Direction direction, HyperEncryptionEventType type)
          Alert all listeners that a HyperEncryptionEvent has occurred.
 Contact getOwner()
          Gets the e-mail contact of the owner of this HyperCollector.
 boolean hasContact(Contact c)
          Returns true iff this collector has storages for the given contact.
 void makeBlocks(Contact contact, Direction direction)
          Make system and encryption blocks, if possible.
 void newContact(Contact contact, byte[] outgoingSecret, byte[] incomingSecret)
          Creates HyperStorages for contact, and initializes them with blocks created from the given shared secret.
 int numEncBlocks(Contact contact, Direction dir)
          Returns the number of encryption blocks in storage for the given contact and direction.
 int numRPages(Contact contact, Direction dir)
          Returns the number of reconciled pages in storage for the given contact and direction.
 int numSysBlocks(Contact contact, Direction dir)
          Returns the number of system blocks in storage for the given contact and direction.
 int numUPages(Contact contact, Direction dir)
          Returns the number of unreconciled pages in storage for the given contact and direction.
 void receiveRec(Contact contact, HyperMessage message, MessageParser parser)
          Process a slave reconciliation response.
 HyperMessage reconcile(Contact contact, HyperMessage message, MessageParser parser)
          Given the contents of a master reconciliation message, returns a slave reconciliation message indicating the results of the reconciliation.
 void removeHListener(HyperEncryptionListener listener)
          Unregister the given as a listener for this object.
 HyperMessage sendRec(Contact contact, MessageParser parser)
          Returns a master reconciliation message containing an ID-hash pair for each unreconciled page in storage.
 boolean verifyHEMAC(byte[] msgBytes, List<Integer> blocksUsed, HyperMAC expected, Contact contact)
          Verifies the HEMAC of a message.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

BLOCK_LEN

public static final int BLOCK_LEN
Length of a block, in bytes.

See Also:
Constant Field Values

PAGE_LEN

public static final int PAGE_LEN
Length of a page, in bytes.

See Also:
Constant Field Values

PAGES_PER_PAD

public static final int PAGES_PER_PAD
Number of pages that should be combined to form a single page of a one-time pad.

See Also:
Constant Field Values

SYSBLOCKS_PER_PAD

public static final int SYSBLOCKS_PER_PAD
Number of system blocks to create each time a pad is created.

See Also:
Constant Field Values

NUM_SYSBLOCKS

public static final int NUM_SYSBLOCKS
all the blocks necessary to make a new OTP

See Also:
Constant Field Values

RS_SEED_INDEX

public static final int RS_SEED_INDEX
the block to be used as the random seed for our random source

See Also:
Constant Field Values

HASH_ENC

public static final int HASH_ENC
the block to be used to encrypt the hash

See Also:
Constant Field Values

PAGE_SHUF

public static final int PAGE_SHUF
the block to be used as the key to combine to pages into a OTP

See Also:
Constant Field Values
Constructor Detail

HyperCollector

public HyperCollector(Map<Contact,HyperStorage> masterstorages,
                      Map<Contact,HyperStorage> slavestorages,
                      Contact owner,
                      HyperStorageFactory storageFactory)
Constructs a new HyperCollector. A HyperCollector may be initialized with a set of HyperStorages; one way of keeping a persistent state across multiple sessions is to pass HyperStorages with a particular state to this constructor.

When a contact is added using the newContact method and HyperStorages for that contact have not been provided at construction, the storageFactory will be used to create new, empty HyperStorages for the new contact.

Parameters:
masterstorages - Initial set of outgoing block storages.
slavestorages - Initial set of incoming block storages.
owner - The owner of this Collector: the person who is the sender of outgoing messages and recipient of incoming messages. This is usually a Contact representing the user of the hyper-encryption client.
storageFactory - A factory for creating new HyperStorages.
Method Detail

getOwner

public Contact getOwner()
Gets the e-mail contact of the owner of this HyperCollector. The owner is the person who acts as the sender of messages encrypted by this HyperCollector, and as recipient of decrypted messages.


newContact

public void newContact(Contact contact,
                       byte[] outgoingSecret,
                       byte[] incomingSecret)
Creates HyperStorages for contact, and initializes them with blocks created from the given shared secret. The first 128 bytes become 16 encryption blocks; all remaining bytes in the secret turn into 32-byte system blocks. If the number of bytes in either secret is not a multiple of the length of a system block, the extra bytes are discarded.

If the HyperStorages for the contact already exist, appends the given encryption and system blocks to the existing HyperStorages.

Parameters:
contact - The e-mail contact associated with the new contact.
outgoingSecret - A shared secret used to initialize outgoing communication with the contact. This secret is used to initialize encryption/system blocks for outgoing mail (the "master" blocks).
incomingSecret - A shared secret used to initialize incoming communication with the contact. This secret is used to initialize encryption/system blocks for incoming mail (the "slave" blocks).

collectNext

public void collectNext(Contact contact,
                        Direction direction)
                 throws EncryptionException,
                        PageException
Gets a page from a PSN, in the manner indicated by the system blocks. Computes the hash of the page, then stores both in the HyperStorage for contact.

This process consumes one system block from the HyperStorage for contact.

If unable to get a page from the PSN using a particular system block, this method tries each available system block until one succeeds. If all blocks fail to produce pages, then this method throws a PageException.

Parameters:
contact - Contact associated with this page.
direction - If MASTER, adds the collected page to the master page list, else to the slave page list.
Throws:
EncryptionException - If there are no system blocks available.
PageException - If there are system blocks available, but all of them fail to produce a page

sendRec

public HyperMessage sendRec(Contact contact,
                            MessageParser parser)
                     throws EncryptionException
Returns a master reconciliation message containing an ID-hash pair for each unreconciled page in storage. This is the first step in the page reconciliation process.

The ID-hash pairs are in increasing order of their IDs.

Parameters:
contact - the contact with whom to reconcile pages. The reconciliation message will be sent to this contact, using the unreconciled pages associated with this contact.
parser - a MessageParser to be used to encode the master reconciliation hash list as a String
Returns:
a master reconciliation message (to be sent)
Throws:
EncryptionException - if there are not enough encryption blocks available to send this message (encryption blocks are required to authenticate the message)

makeBlocks

public void makeBlocks(Contact contact,
                       Direction direction)
                throws EncryptionException
Make system and encryption blocks, if possible. If there are insufficiently many reconciled pages (i.e., less than PAGES_PER_PAD), an exception occurs. Otherwise, this method consumes PAGES_PER_PAD reconciled pages, creates SYSBLOCKS_PER_PAD system blocks, then creates as many encryption blocks as possible (specifically, PAGE_LEN/BLOCK_LEN - (SYSBLOCKS_PER_PAD*NUM_SYSBLOCKS) encryption blocks).

Parameters:
contact - the contact for whom to create blocks. The blocks will be produced from the reconciled pages associated with this contact.
direction - if MASTER, adds the produced blocks to the master block list, else to the slave block list.
Throws:
EncryptionException - if there are fewer than PAGES_PER_PAD reconciled pages available
IllegalArgumentException - if contact is not a valid contact (specifically, if there are no pages or blocks stored)

reconcile

public HyperMessage reconcile(Contact contact,
                              HyperMessage message,
                              MessageParser parser)
                       throws MessageParseException
Given the contents of a master reconciliation message, returns a slave reconciliation message indicating the results of the reconciliation. This is the second step in the reconciliation process.

Parameters:
contact - the contact with whom to reconcile pages. The reconciliation response will be sent to this contact, and the reconciliation will be performed using the pages associated with this contact.
message - master reconciliation message
parser - a MessageParser to be used to parse message
Returns:
a slave reconciliation message describing the results of the reconciliation
Throws:
MessageParseException - if parser fails to parse message

receiveRec

public void receiveRec(Contact contact,
                       HyperMessage message,
                       MessageParser parser)
                throws MessageParseException
Process a slave reconciliation response. This is the third and final step in the reconciliation process.

Parameters:
contact - the contact with whom to reconcile pages. This is the contact from whom message was received; the reconciliation involves the pages associated with this contact.
message - response to reconciliation message
parser - a MessageParser to be used to parse message
Throws:
MessageParseException - if parser fails to parse message

verifyHEMAC

public boolean verifyHEMAC(byte[] msgBytes,
                           List<Integer> blocksUsed,
                           HyperMAC expected,
                           Contact contact)
                    throws BlockMissingException
Verifies the HEMAC of a message. Computes what the HEMAC should be, given the parameters, and compares the result to expected.

If blocksUsed is present (non-null and non-empty), the contained integers are converted to big-endian four-byte arrays and appended to msgBytes. Then the encryption blocks whose IDs are specified by expected.getBlockList() are concatenated together to form a 512-bit key, which is used to compute the MAC of msgBytes. The encryption blocks are drawn from the incoming block storage for contact.

Parameters:
msgBytes - the message for which to compute the MAC
blocksUsed - if present, these integers are appended to msgBytes before the MAC is computed. This option exists to allow the encryption block ID list that accompanies the ciphertext to be authenticated as well. May be null or empty, in which case nothing is appended to msgBytes.
expected - the MAC to be verified. If the computed MAC equals expected.getMac(), then expected is said to be valid. If not, it is invalid.
contact - the Contact from whom the message and MAC were received. The encryption blocks from the incoming HyperStorage for this contact are used in computing the MAC. The encryption blocks are removed from this HyperStorage if and only if the MAC verifies. If the expected MAC does not match the computed MAC, the HyperStorage is left unchanged. afterwards, if desired.
Returns:
true iff the expected MAC is valid.
Throws:
BlockMissingException - if one or more of the encryption block IDs given in expected.getBlockList() is not present in the HyperStorage for contact. If this exception is thrown, the MAC is considered to be invalid.

encrypt

public HyperMessage encrypt(HyperMessage unencrypted)
                     throws EncryptionException
Encrypts a message. The content of unencrypted is encrypted using the encryption blocks associated with the recipient of unencrypted. The subject is not encrypted.

The returned HyperMessage has the same subject, sender, recipient, and date as the given unencrypted HyperMessage. Its type is HyperMessageType.ENCRYPTED. Its content is the encrypted content of unencrypted, and its padsUsed field is the list of encryption block IDs used to encrypt the content.

Parameters:
unencrypted - a HyperMessage containing the message to be encrypted
Returns:
A HyperMessage containing the encrypted message.
Throws:
EncryptionException - if there are not enough encryption blocks available to encrypt this message
IllegalArgumentException - if unencrypted is already encrypted

decrypt

public HyperMessage decrypt(HyperMessage encryptedMessage)
                     throws BlockMissingException
Decrypt message. Uses the encryption blocks associated with the sender of the encrypted message (as determined by the getSender method).

The returned HyperMessage has the same subject, sender, recipient, and date as the given encrypted HyperMessage. Its type is HyperMessageType.UNENCRYPTED. Its content is the decrypted content of encryptedMessage, and its padsUsed field is null.

Parameters:
encryptedMessage - message to decrypt
Returns:
A HyperMessage containing the decrypted message.
Throws:
BlockMissingException - if an encryption block required for decryption is not available

hasContact

public boolean hasContact(Contact c)
Returns true iff this collector has storages for the given contact.

Parameters:
c - a Contact
Returns:
if this collector has storages for c

numSysBlocks

public int numSysBlocks(Contact contact,
                        Direction dir)
Returns the number of system blocks in storage for the given contact and direction.

Parameters:
contact - contact
dir - direction of communication
Returns:
the number of system blocks available for communication with the given contact in the given direction
Throws:
IllegalArgumentException - if storages for contact do not exist. Check whether this is the case using hasContact. To fix this, create the contact using newContact.

numEncBlocks

public int numEncBlocks(Contact contact,
                        Direction dir)
Returns the number of encryption blocks in storage for the given contact and direction.

Parameters:
contact - contact
dir - direction of communication
Returns:
the number of encryption blocks available for communication with the given contact in the given direction
Throws:
IllegalArgumentException - if storages for contact do not exist. Check whether this is the case using hasContact. To fix this, create the contact using newContact.

numUPages

public int numUPages(Contact contact,
                     Direction dir)
Returns the number of unreconciled pages in storage for the given contact and direction.

Parameters:
contact - contact
dir - direction of communication
Returns:
the number of unreconciled pages available for communication with the given contact in the given direction
Throws:
IllegalArgumentException - if storages for contact do not exist. Check whether this is the case using hasContact. To fix this, create the contact using newContact.

numRPages

public int numRPages(Contact contact,
                     Direction dir)
Returns the number of reconciled pages in storage for the given contact and direction.

Parameters:
contact - contact
dir - direction of communication
Returns:
the number of reconciled pages available for communication with the given contact in the given direction
Throws:
IllegalArgumentException - if storages for contact do not exist. Check whether this is the case using hasContact. To fix this, create the contact using newContact.

addHListener

public void addHListener(HyperEncryptionListener listener)
Register interest in HyperEncryptionEvents. listener will receive events fired from this HyperCollector.


removeHListener

public void removeHListener(HyperEncryptionListener listener)
Unregister the given as a listener for this object. listener will no longer receive events fired from this HyperCollector. If listener was not listening to this HyperCollector, does nothing.


fireHEvent

protected void fireHEvent(Contact contact,
                          Direction direction,
                          HyperEncryptionEventType type)
Alert all listeners that a HyperEncryptionEvent has occurred.

Parameters:
contact - the contact whose data was affected by the event being fired
direction - whether the event was generated by a master or a slave storage
type - Indicates the type of event that occurred.