This is a zero-trust Secret Santa algorithm & implementation.
The goal is to create a single web page that can distribute assignments via out-of-band communications executed by the participants, with no server-side state, and no ability to alter or observe the results besides one's own.
This is done in three cycles:
An extra layer of complexity is introduced by the ability for some agents to infer the ownership of a key. Specifically the second agent and the second-to-last agent can know who the first key's owner is and the last keys owner, respectively. This can be resolved by encrypting the public keys and the assignments with another public key, generated by the first agent. Only when all keys or assignments are added are they all decrypted by the first agent in the ring.
+---+ +---+ +---+
| A | | B | | C |
+---+ +---+ +---+
| | |
1. generate a wrapping key | |
2. generate an assignment | |
key | |
3. save both private keys | |
to cookie | |
3. encrypt assignment key | |
with wrapping key | |
| | |
|------send B a URL with | |
| wrapping key and | |
| encrypted assignment | |
| key------------------->| |
| | |
| 1. generate an assignment |
| key |
| 2. save private key to |
| a cookie |
| | |
| |---send C a URL with |
| | wrapping key and |
| | B's and A's assignment |
| | keys--------------------->|
| | |
| | 1. generate an assignment
| | key
| | 2. save private key to
| | a cookie
| | |
| | send A a URL with------|
| | B's and A's and |
|<-----------------------------------C's assignment keys |
| | |
1. unwrap all assignment keys | |
2. encrypt assignment for self | |
3. re-encrypt with wrapping key | |
| | |
|----send B a URL with | |
| 2x encrypted | |
| assignment-------------->| |
| | |
| 1. encrypt assignment for self |
| 2. re-encrypt with wrapping key |
| | |
| |----send C a URL with |
| | 2x encrypted |
| | assignments for A & B--->|
| | |
| | 1. encrypt assignment for self
| | 2. re-encrypt with wrapping key
| | |
| | send A a URL with-------|
| | all 2x encrypted |
|<----------------------------------assignments |
| | |
1. decrypt all assignments | |
with wrapping key | |
2. decrypt own assignment | |
with assignment key | |
| | |
|----send B a URL with | |
| all decrypted | |
| assignments------------->| |
| | |
| 1. decrypt own assignment |
| with assignment key |
| | |
| |----send C a URL with |
| | all decrypted |
| | assignments------------->|
| | |
| | 1. decrypt own assignment
| | with assignment key
| | |
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
The source code can be found by right-clicking > View source, or in the Git repository here:
https://git.sr.ht/~jonahbron/jonah.id/tree/main/item/content/tools/secret-santa.html
The usage of shuffling/shifting is drawn from the Hannah Fry Numberphile video about Secret Santa.
https://youtu.be/5kC5k5QBqcc