How to hand out bridges. Divide bridges into 'strategies' as they come in. Do this uniformly at random for now. For each strategy, we'll hand out bridges in a different way to clients. This document describes two strategies: email-based and IP-based. 0. Notation: HMAC(k,v) : an HMAC of v using the key k. A|B: The string A concatenated with the string B. 1. Email-based. Goal: bootstrap based on one or more popular email service's sybil prevention algorithms. Parameters: HMAC -- an HMAC function P -- a time period K -- the number of bridges to send in a period. Setup: Generate two nonces, N and M. As bridges arrive, put them into a ring according to HMAC(N,ID) where ID is the bridges's identity digest. Divide time into divisions of length P. When we get an email: If it's not from a supported email service, reject it. If we already sent a response to that email address (normalized) in this period, send _exactly_ the same response. If it is from a supported service, generate X = HMAC(M,PS|E) where E is the lowercased normalized email address for the user, and where PS is the start of the currrent period. Send the first K bridges in the ring after point X. To normalize an email address: Start with the RFC822 address. Consider only the mailbox {???} portion of the address (username@host). Put this into lowercase ascii. Questions: What to do with weird character encodings? Look up the RFC. Notes: Make sure that you can't force a single email address to appear in lots of different ways. IOW, if nickm@freehaven.net and NICKM@freehaven.net aren't treated the same, then I can get lots more bridges than I should. Make sure you can't construct a distinct address to match an existing one. IOW, if we treat nickm@X and nickm@Y as the same user, then anybody can register nickm@Z and use it to tell which bridges nickm@X got (or would get). Make sure that we actually check headers so we can't be trivially used to sapam people. 2. IP-based. Goal: avoid handing out all the bridges to users in a similar IP space and time. Parameters: T_Flush -- how long it should take a user on a single network to see a whole cluster of bridges. N_C K -- the number of bridges we hand out in response to a single request. Setup: using an AS map or a geoip map or some other flawed input source, divide IP space into "areas" such that surveying a large collection of "areas" is hard. For v0, use /24 adress blocks. Group areas into N_C clusters. Generate nonces L, M, N. Set the period P such that P*(bridges-per-cluster/K) = T_flush. Don't set P to greater than a week, or less than three hours. When we get a bridge: Based on HMAC(L,ID), assign the bridge to a cluster. Within each cluster, keep the bridges in a ring based on HMAC(M,ID). When we get a connection: If it's http, redirect it to https. Let net be the incoming IP network. Let PS be the current period. Compute X = HMAC(N, PS|net). Return the next K bridges in the ring after X. 3. Open issues Denial of service attacks A good view of network topology