#\". So, the chatacter X is
written as "#\X". Lookup "character" in the
Scheme language definition, and you'll see all the standard
functions Scheme provides. Particularly useful for us are
char->integer and integer->char.
Example:
> (char->integer #\X) 88 > (integer->char 88) #\X
String literals in Scheme are defined just like you'd
expect: characters within quotation marks. So, for example,
the Scheme literal for the string "Hello World" is simply
"Hello World". Lookup "string" in the standard
Scheme language definition and you'll see all the standard
functions Scheme provides. Particularly useful for us are
string->list and list->string.
Example:
> (string->list "Hi there!") (#\H #\i #\space #\t #\h #\e #\r #\e #\!) > (list->string '(#\o #\u #\c #\h)) "ouch"
(gcd u v) returns ... the gcd of u and v
(egcd u v) returns the list (g,s,t) where g=gcd(u,v) and s*u + t*v = g.
(modexp b e n) computes b^e mod n
(random-n-bit-prime n) returns a random n bit prime number (or with
some small probability n+1), by which I mean the prime is
represented by n bits, but cannot be represented by n-1 bits.
(char->8bits c) returns a list of 8 bits comprising the binary rep of c.
(int->8bits x) returns a lits of 8 bits comprising the binary rep of
the number x, where 0<= x < 256.
(bits->integer L) returns an integer L resulting from interpreting the
the list L, which should contain only 0s and 1s, as the binary
representation of an integer.
The file rsahelp.scm
can be loaded into your scheme file with
(load "/home/wcbrown/courses/SI333/projects/P03/rsahelp.scm").
Hopefully these will help you out in your RSA implementation!
Otherwise, any code we've done in class, and any functions in
standard scheme or in drscheme are fair game. Do not
get other code from the web!
(genkey) that produces a random
pair (pub pri), where pub is a public key and pri
is a private key. The key size must be sufficient for
encrypting 32-bits at a time. In the following, a random key
is generated, and then tested to ensure that encrypting
the randomly chosen value 897879 with the public key followed
by decrypting with the private key really yields back the
original value.
> (genkey) ((3727026301 12006626903) (8875703221 12006626903)) > (define e 3727026301) > (define d 8875703221) > (define n 12006626903) > (modexp (modexp 897879 e n) d n) 897879 >
(encrypt text key) that takes a
string text and a public key pair
key of the form (e n) and returns a
list of numbers representing the encryption of
text using the key (e n).
Since we're encrypting text in 4-character chunks, your program may
have to pad messages with one or two or three spaces. Whether this
padding is at the beginning or the end I don't care.
Example:
> (genkey) ((2182022257 5416008431) (4463056321 5416008431)) > (encrypt "hello world!" '(2182022257 5416008431)) (4811401772 3821742299 1646026913) >Note that no padding was required for this example because the input is 12 characters long.
(decrypt L key) that takes a
list of numbers representing an encoded message and a private
key pair key of the form (d n) and
returns a string representing the decrypted value of L using
(d n).
Example:
> (decrypt '(4811401772 3821742299 1646026913) '(4463056321 5416008431)) "hello world!" >
> (define keys (genkey)) > (define public (car keys)) > (define private (cadr keys)) > (define M "hello world!") > (define Mp (encrypt M public)) > (decrypt Mp private) "hello world!" >Test your project. There's no excuse for submitting something that doesn't work when, in this case, testing is so easy. Please check that your project works for messages whose length is not a multiple of 4, like "seven". The decrypted message may differ from the original only by having some extra padding spaces at the beginning or the end.
Your submitted project should include all your function definitions, which must match the specifications given above - names, number of arguments, and everything. Your name should appear in a comment, and your code must be well formatted and documented. If your printout has lines that wrap around because they're too long, either decrease the font size, print landscape, or reformat the scheme code so no line is too long. I'd also appreciate it if my file rsahelp.scm is included with a "load" statment rather than copied and pasted into the file.
/courses/wcbrown/bin/SI333-submit <alpha>.scm
Five more extra credit points if you can implement authenticated encrypt and decrypt functions. Authentication doesn't change key generation, of course, it just changes encryption and decryption since everything's encrypted twice. Here's an example:
Define public/private keys for Alice > (define alice-key (genkey)) > (define alice-public (car alice-key)) > (define alice-private (cadr alice-key)) > alice-key ((7641946489 12431595247) (7821355609 12431595247)) Define public/private keys for Bob > (define bob-key (genkey)) > (define bob-public (car bob-key)) > (define bob-private (cadr bob-key)) > bob-key ((9589270111 10644146593) (7563753751 10644146593)) Alice sends Bob a message that only he can read, and that only she could've sent > (define Mp (authenticated-encrypt "the duck swims at noon" bob-public alice-private)) > Mp (8037239302 8203794522 4678930754 1718497391 2665249581 2635568077 8304205620 2744699074 8070489252 2257376086 10010155244 9406650820 2577370953 5156123487 1591226022 3033898094 3395889913) Bob decodes the message and, since Alice's public key is required, is sure she sent it > (authenticated-decrypt Mp bob-private alice-public) "the duck swims at noon " > Let's see what's done step-by-step! > (decrypt Mp bob-private) "(5689361715 7823470547 12251671233 1163320656 3518120403 8480230455)" > (decrypt '(5689361715 7823470547 12251671233 1163320656 3518120403 8480230455) alice-public) "the duck swims at noon " >
To do this right, you're going to do I/O operations
(read and write) on strings.
The Scheme language underlying drscheem, mzscheme, has
nice facilities for this.
Look at the
PLT MzScheme Language Manual.
In particular, check out
11.1.5 String Ports.
It provides a little HelloWorld-esque example to show
you how these things work. We haven't used
read and write, because we
haven't done I/O!
To submit: just e-mail me your source for this.