Yes there is. I've been puzzeling over this one for years and after reading the answers her I think I've figured it out.
The approach involves two steps like @hmalcom left over monica's work above, and depends on a couple of primitives that we'll assume exist as well as a public communication channel.
Primitives
random number selection.
The goal is for each person to contribute randomness but in a way that cannot be manipulated to their benefit later.
First each person generates a random number, Second, they compute a cryptographic hash of that number and post the hash publicly.
Later, then the random number is required, each person posts the underlying random number and participants validate that the random numbers do generate the hashes posted earlier. Any thay don't match are discarded. The remainimg are xor'ed together as binary numbers to get a random seed.
I'll refer to these as the randumom number(s) amd their precommits.
public/private key encryption
This is the standard sets of public/private keypairs, with the requirement that their format doesn't contain any identifying information.
a public communication channel
Each participant needs read/write permissions in this channel.
Algorithm
The basic version will take three public/private keypairs per person, two precommits for random number, and the public communication channel.
Establish identities
First, each participant publishes one of their public keys and the two random number preecommits.
Thes public keys will be used to encrypt communication between participants while the random numbers associated with the precommits will be used to sort some lists.
create an anonomous list of public keys.
Now we must create an ordered list of participants, and then randomize the list using the random numbers associated with the first precommits provided.
This list will determine the order in which participants submit information.
The first participant encrypts their second public key with the communication key of the second perwon and sends them the message.
Each remaining participant does the following:
- Decrypt the message they are sent
- add their own second public key to the list of public keys
- reorder the list randomly
- encrypt and send it to the next participant in the list.
When it reaches the last participant in the list, they do the same as above, sending it to the first participant.
It is of utmost importance that all of these communications be encrypted.
Once the first participant recieves the message from the last, they will:
- decrypt the message
- replace their second public key with the third public key.
- randomly shuffles the list of public keys. (this is the last permanent shuffle)
- make a copy of this shuffled list, encrypted with the second participant's public key, and send it to them.
- use the random number from the second set of precommits, and shuffle the list using the agreed upon random number as the seed.
- they then takes the order of this list, finds theirself on it, and grabs the public key. immediately following their own. This who will be who will send them a present.
- They then encrypt a message to this person with their name, contact details (if mailimg presents), and critical information such as allergies and religious prohibitions thay might apply.
- they then publish this encrypted message, ensuring that it does not include any information on the public/private key pair that it is destined for.
- they delete their copy list of participants they created.
Each participant after will follow a similar pattern.
- decrypt
- replace their key
- DO NOT SHUFFLE THE LIST
- make a copy of the list
- encrypt the original list and send it to the next participant.
- shuffle the list based on the random number given by the second set of precommits.
- find the person who's public key follows theirs
- encrypt their identifying information with that public key and post it to the communication channel.
As these encrypted messages are posted, each participant tries to decrypt them with both of the keys they have provided. When they decrypt one, it will contain the information of the person they are buying for.
how this works
Consider the information each participant has during each of their turns.
During the first round, each participant can identify which participants came before them, and thus could identify who came after if they obtain a plaintext copy of the list.
For example, the second and penultimate participants can associate the keys of the first and last participants to their identities.
The shuffling step during each participant's turn eliminates the possibility of associating keys to participants through order information.
During the second round, participants lose the positional information they may have gathered.
For each participant, when it gets to them, they see the (previously unobserved) keys from those after them and the updated keys of those before them. As these are both previously unobserved, the participamt cannot tell between them, as long as nobody else leaks their view.
There is a bit to say about potential attacks and the impact of leaking informatiom, but I'll do that when I have something other than my phone to type on.