M bulletin.rkt => bulletin.rkt +37 -23
@@ 2,6 2,7 @@
(require racket/contract
racket/list
racket/match
+ racket/random
racket/set
racket/string)
(require web-server/servlet
@@ 9,9 10,10 @@
json)
(require simple-http)
(require readline/readline)
+(require (only-in openssl/sha1 bytes->hex-string))
(define state 'registering)
-(define _peers (mutable-set))
+(define _peers (make-hasheq))
(define _commits (make-hash))
(define _outputs (make-hash))
(define _sums (make-hash))
@@ 70,11 72,15 @@
[password (hash-ref params 'password)]
[input (hash-ref params 'input)])
(if (auth username password)
- (begin
+ (let* ([token (crypto-random-bytes 128)]
+ [token (bytes->hex-string token)])
(displayln (format "~a is voting! (~a)" username input))
- (set-add! _peers (hasheq 'input input
- 'username username))
- (response/jsexpr empty))
+ (hash-set! _peers (string->symbol token)
+ (hasheq 'input input
+ 'username username))
+ ; send the token that the peer will use for further
+ ; authorization
+ (response/jsexpr token))
(response/jsexpr
"Bad Login"
#:code 400)))
@@ 85,23 91,25 @@
(define (peer-count request)
(if (eq? state 'committing)
- (response/jsexpr (set-count _peers))
+ (response/jsexpr (hash-count _peers))
(response/jsexpr
"Committing has not begun"
#:code 403)))
(define (commit request)
(if (eq? state 'committing)
- (let ([params (bytes->jsexpr (request-post-data/raw request))])
+ (let* ([params (bytes->jsexpr (request-post-data/raw request))]
+ [peer (hash-ref _peers (string->symbol
+ (hash-ref params 'token)))])
(displayln params)
- (hash-set! _commits (hash-ref params 'input)
+ (hash-set! _commits (hash-ref peer 'input)
(hasheq 'p (hash-ref params 'p))
; TODO: D polynomial
;; (hasheq 'd (hash-ref params 'd))
)
; has everyone committed?
(when (eqv? (hash-count _commits)
- (set-count _peers))
+ (hash-count _peers))
(transition))
(response/jsexpr empty))
(response/jsexpr "Not in the committing phase"
@@ 109,7 117,7 @@
(define (peers request)
(if (eq? state 'voting)
- (response/jsexpr (for/list ([v _peers])
+ (response/jsexpr (for/list ([v (hash-values _peers)])
(hash-ref v 'input)))
(response/jsexpr
"Voting has not begun"
@@ 117,17 125,19 @@
(define (outputs request)
(if (eq? state 'voting)
- (begin
+ (let* ([params (bytes->jsexpr (request-post-data/raw request))]
+ ; ensure this is a registered peer
+ [peer (hash-ref _peers (string->symbol
+ (hash-ref params 'token)))])
; TODO: check validity of inputs
- (let ([params (bytes->jsexpr (request-post-data/raw request))])
- (for ([(p v) params])
- (hash-update! _outputs
- (symbol->string p)
- (λ (l) (cons v l)) empty)))
+ (for ([(p v) (hash-ref params 'outputs)])
+ (hash-update! _outputs
+ (symbol->string p)
+ (λ (l) (cons v l)) empty))
; has everyone submitted their outputs?
(when (for/and ([(p v) _outputs])
(eqv? (length v)
- (set-count _peers)))
+ (hash-count _peers)))
(transition))
(response/jsexpr empty))
(response/jsexpr
@@ 136,9 146,11 @@
(define (_values request)
(if (eq? state 'summing)
- (let ([input (hash-ref (bytes->jsexpr (request-post-data/raw request)) 'input)])
+ (let* ([params (bytes->jsexpr (request-post-data/raw request))]
+ [peer (hash-ref _peers (string->symbol
+ (hash-ref params 'token)))])
(response/jsexpr
- (hash-ref _outputs input)))
+ (hash-ref _outputs (hash-ref peer 'input))))
(response/jsexpr
"This election is not in the summing phase"
#:code 403)))
@@ 146,8 158,10 @@
(define (sum request)
(if (eq? state 'summing)
(let* ([params (bytes->jsexpr (request-post-data/raw request))]
- [input (string->symbol (hash-ref params 'input))]
- [sum (hash-ref params 'sum)])
+ [peer (hash-ref _peers (string->symbol
+ (hash-ref params 'token)))]
+ [input (string->symbol (hash-ref peer 'input))]
+ [sum (hash-ref params 'sum)])
(hash-set! _sums input sum)
(response/jsexpr
empty))
@@ 157,7 171,7 @@
(define (sums request)
(if (eq? (length (hash-keys _sums))
- (set-count _peers))
+ (hash-count _peers))
(response/jsexpr
_sums)
(response/jsexpr
@@ 217,7 231,7 @@
['cands
(displayln (hash-ref election->candidates election))]
['peers
- (displayln _peers)])]
+ (displayln (hash-values _peers))])]
['set (match (read sp)
['election (let ([election (read sp)])
(election-set! election))]
M client.rkt => client.rkt +25 -24
@@ 66,20 66,21 @@
(define bulletin
(update-port (update-host json-requester "localhost") 1984))
- (void
- (let ([username (readline "Username: ")]
- [password (get-pass "Password: ")])
- (with-handlers ([exn:fail:network:http:error?
- (λ ([ex : exn:fail:network:http:error])
- (newline)
- (displayln (format "Login refused: ~a"
- (exn-message ex)))
- (exit))])
- (post bulletin "/register"
- #:data
- (jsexpr->string (hasheq 'input (integer->hex-string point)
- 'username username
- 'password password))))))
+ (define token
+ (let ([username (readline "Username: ")]
+ [password (get-pass "Password: ")])
+ (with-handlers ([exn:fail:network:http:error?
+ (λ ([ex : exn:fail:network:http:error])
+ (newline)
+ (displayln (format "Login refused: ~a"
+ (exn-message ex)))
+ (exit))])
+ (json-response-body
+ (post bulletin "/register"
+ #:data
+ (jsexpr->string (hasheq 'input (integer->hex-string point)
+ 'username username
+ 'password password)))))))
(displayln "retrieving candidates...")
(define candidates (cast (json-response-body
@@ 155,8 156,7 @@
#:data
(jsexpr->string
(hasheq
- 'input
- (integer->hex-string point)
+ 'token token
'p
(bytes->hex-string
(merkle-node-hsh
@@ 177,10 177,13 @@
(post bulletin "/outputs"
#:data
(jsexpr->string
- (for/hasheq : (Immutable-HashTable Symbol String)
- ([p : Integer (cast peer-inputs (Listof Integer))])
- (values (string->symbol (integer->hex-string p))
- (integer->hex-string (poly p)))))))
+ (hasheq
+ 'token token
+ 'outputs
+ (for/hasheq : (Immutable-HashTable Symbol String)
+ ([p : Integer (cast peer-inputs (Listof Integer))])
+ (values (string->symbol (integer->hex-string p))
+ (integer->hex-string (poly p))))))))
(display "summing...")
(void
@@ 188,8 191,7 @@
#:data
(jsexpr->string
(hasheq
- 'input
- (integer->hex-string point)
+ 'token token
'sum
(integer->hex-string
(foldl + 0
@@ 200,8 202,7 @@
(post bulletin "/values"
#:data
(jsexpr->string
- (hasheq 'input
- (integer->hex-string point))))))
+ (hasheq 'token token)))))
(Listof String)))))))))
(newline)