Newsgroups: sci.crypt Path: sparky!uunet!cs.utexas.edu!asuvax!ncar!sage.cgd.ucar.edu!prz From: p...@sage.cgd.ucar.edu (Philip Zimmermann) Subject: Colston's Quick Public Key scheme Message-ID: <1992Jun28.040947.7642@ncar.ucar.edu> Summary: Fast public key algorithm Sender: ne...@ncar.ucar.edu (USENET Maintenance) Organization: none Date: Sun, 28 Jun 1992 04:09:47 GMT Lines: 387 I'm posting this document for a friend, David Colston, who does not have access to Internet. If you have any comments, you can reply directly to him via phone, or snail mail, or you can reply to me and I can forward your comments to him (but not as fast). His article refers to some software he developed, which can be obtained directly from David Colston. -Philip Zimmermann Article follows... -------------------------------------------------------------------- QUICK PUBLIC KEY (Q.P.K.) v. 1.0 Copyright 1992 By Colston & Associates, Inc. If you hate math skip down to the useage section. Math notation: + plus - minus +- plus or minus * multiplication / division ^ exponent <> unequal = equals == congruent < less than > greater than INT truncated integer round SQR square root ( open expression ) close expression x^-1 modulo p the multiplicative inverse of x in the field of p x... y the range of values Variables in capital letters are permanent and those in small letters are temporary. BACKGROUND Because the "secret key" function of RSA is so slow, most cryptographers use the RSA function only to "boot strap" into a conventional key system, which is faster to send the actual message. Most of the conventional key systems use comparatively small numbers in relation to the size of the public N as a "random seed number". The holder of the secret key may actually have a larger amount of computer time to decipher the starting point of the conventional algorithm than to decipher the actual message. It would seem to be a good idea, if a public key function could take advantage of the actual message size required to speed up the public key process. Here is an idea on this subject. The range of message sizes is described below, but generally speaking we a discussing messages less than SQR(Q) in actual size. Imagine a series of related equations modulo a prime, P. These equations have the formula ((e * e + e)/2 * L + C) modulo P. The value, C, is a constant determined by the rule (L - 1) * (1 / (2 * L)) modulo P == C. For L = 1, C = 0. Therefore, if L is known, the expression ((e * e + e)/2) modulo P may be determined, even if e is unknown. The range of message sizes is described below, but generally speaking we a discussing messages less than SQR(Q) in actual size. Each value of L has an area or series of areas, in which the value of e becomes discoverable, WITHOUT resorting to a modular square root. ie. Let r == ((e * e + e)/2 * L + C) modulo P. If e is in the correct range relative to L, then (r * L * 8 + (L - 2) * (L - 2)) will have an integer square root and the value, e, may be determined with ease. The range of values of e, for any value of L, which have this property and the location of those values vary greatly. The following illustrates a public key approach for L = 12, but other values of L may also be used. Perhaps I should also note that the particular L, which a secret key holder uses need not be public knowledge, but is not all that sensitive. ESTABLISHING A Q.P.K. KEY BASED ON L = 12 A person wishing to receive public messages, which he/she alone can decrypt calculates N = P * Q. Where P and Q are a randomly selected prime numbers, Q being the larger. A == (11 * 24^-1 ) modulo Q B == (2 * A) modulo Q D = Q - B If D > (Q - 1)/2 then set D = Q - D - 1. F = (Q - 1)/2 - D NOTE: We may chose to use the F for all of the following calculations instead of D. This applies to no value of L lower than 12 and F is not valid for most sequences higher than 12. F may be an even safer value to use, for reasons which are too long to discuss here. L is NOT super-sensitive information. Q.P.K. Uses L = 3. Let Y1 ... Y2 be a range of numbers with in the limits: (D - k) and (D + k), where k = INT(SQR(2 * Q / 12)). Y1 may be randomly selected from any point in this range, but Y2 may not be larger than (D + k), and Y2 - Y1 is the maximum message size. A message range for N, public information, is then created by using Chinese remainder theorem to find the modular intersection Q == Y1 and P == x, x being a random number in the range x > 0, x < P. This intersection is called S. A check is made to verify the following: A' = (11 * 24^-1) modulo N B' == (2 * A') modulo N D' = N - B' If D' > (N - 1)/2 then Set D' = N - D' - 1 NOTE: P, Q, D, F, Y1, Y2, k, A, AND B are secret values. Q.P.K. ENCRYPTION A public key for short messages consists of S and N. To send a Message the sender calculates: e = (S + Message) ((e * e + e)/2) modulo N == Cipher Q.P.K. DECRYPTION t == Cipher modulo Q f == (t * 12 + A) modulo Q g = SQR(f * 8 * 12 + 100) NOTE: If g is NOT an integer value, the message is rejected as invalid. If g modulo (2 * L) <> (L - 2) then Q is repetitively added to g until g modulo (2 * L) == (L - 2). z = (g - 10)/24 e == ((B - 1) + z) modulo Q If e > (Q - 1)/2 then set e = (Q - 1) - e. Message = e - Y1 For other values of L: A == ((L - 1) * 2^-1* L^-1)) modulo Q k = INT(SQR(2 * Q / L)) NOTE: If L = 1 then D = 0 and the message range is 1... k. If L = 2 then the message range is D... (Q - 1)/2 and these values modulo Q are already perfect squares < Q. f == (t * L + A) modulo Q g = SQR(f * 8 * L + (L - 2) ^ 2) z = (g - (L - 2)/(L * 2)) I have been told that this idea is based on Rabin and Williams. I will leave that decision to the reader. The point is that it involves a NON-MODULAR SQUARE ROOT and is therefore much faster than exponentiation modulo N. If this algorithm is Rabin, it's in the public domain. If it's not Rabin, but mine, I hereby place it in the public domain. The Q.P.K. program uses this approach to send 4 large "random number seeds". The seeds are used by a conventional decryption algorithm. This conventional key is like a huge "tear sheet" for entire N sized blocks of code. New random are used for each send and receive secession. This is fairly quick stuff, after initialization (although I do admit there are faster algorithms). How does it work? Think of two rows of numbers, with each row having (N - 1) numbers. Each row has a random value for the first number of the row and each subsequent number is determined by adding a random constant to the previous value (a different constant for each row and modulo N, of course). Find your message in the first row. Send the number at that has the same location in the second row. The receiver finds out the position of the number you sent in row two and "looks" up the corresponding value in the first row. Even knowing one row is not enough to decrypt the message. If N has 64 bytes, then each block of 64 characters which are sent can have (N - 1) or about 2 ^ 512 possible values. A change in only one bit of the block will change the entire output block. To summarize, any value sent for a message can be 0 to (N-1) and each has an equal chance of being the correct value. Just in case we're sending the same block of characters over and over again, (ie. pages of spaces) two characters in each block are dummies. The first character in each send block tells the receiving program which other character is null. Mathematically it works this way: R1 = Random Seed 1 R2 = Random Seed 2 R3 = Random Seed 3 R4 = Random Seed 4 IR2 = R2 ^ -1 modulo N IR4 = R4 ^ -1 modulo N ENCRYPT: M = Message. C = Cipher_text. (IR2 * (M - R1)) modulo N = Message_Index NOTE: Message_Index + 1 = the position at which M falls in the first row. C == (R3 + Message_Index * R4) modulo N NOTE: C is the number which occupies the same position in the second row that M occupies in the first column. DECRYPT: (IR4 * (C - R3)) modulo N = Message_Index NOTE: Message_Index + 1 = the row on which the cipher text falls in row 2. It was previously unknown to the receiver. M == (R1 + Message_Index * R2) modulo N PROGRAM USAGE The Start File is labeled "QPK.EXE" amazingly enough. There are a total of seven executable files. QPK.EXE, MAKEKEY.EXE, MAKEKEY2.EXE, MAKEKEY3.EXE, PUBSEND.EXE, PUBGET.EXE, AND BRT71EFR.EXE. The Program assumes that all of these files are in the same directory. QPK is menu driven. It does not have all the features that I would like, just yet. It is intended primarily as demonstration code, but it works well as a public key system. If enough people are interested, I will include an "electronic signature" in the next edition. That way you can not only get messages that you alone can read, but you can know for sure who sent it. If you don't understand what a public key is, it's sort of an "eyes only" message. After you have generated your own random key from the Q.P.K. menu. You can receive messages from anyone who has your public key that only you can interpret (or decrypt as a cryptographer would say)! How, because each public key has a secret key, which is associated with it and you are the only one with the secret key. Conversely, if you have someone else's public key, your can send a message file, which only they can decrypt, To make sure of this you must do only three things: 1) PROTECT YOUR HARD DISK (AND BACKUPS) AND DON"T GIVE ANYONE YOUR MYKEY.SEC OR MYKEY2.SEC FILES! 2) Make sure that anyone that you wish to receive messages from has YOUR public key file and a copy of QPK. Use the main QPK menu to place your key in another file, for example - JOHN.PUB. COLSTON.PUB is include with this offering. 3) You public key is placed in KEYLIST.PUB as the first key when your secret key is generated. (IF YOU HAVE AN OLD KEY IT WILL BE OVER WRITTEN IN KEYLIST.PUB, MYKEY.SEC, AND MYKEY2.SEC. The key will have your name, the date the key was generated, and a number which is associated with that key. Be sure the person who wishes to send you a message has the key number, key date, and your name as entered for key generation, so that a substitution cannot be made. This prevents someone else from substituting a "fake key" that they generated, pretending to be you, and getting confidential messages really intended for YOU. You may use this program for free, as well as the all the source code (Q.P.K. is written in Microsoft (R) Quick Basic V 7.1) for any non-commercial purpose. If you wish to be on a mailing list for updates, write to: Colston and Associates, Inc. 5111 Rogers Ave. Suite 507 Fort Smith, AR 72703 Day phone (501) 452-4948 Home (501) 785-2208 In addition to writing or calling the above address, you may reach me by E-Mail for questions or to make comments: c/o Charles Merritt 7120...@compuserve.com Bix User I.D.- charliemerritt (for those of you on BIX) I am available for consultation for commercial applications (for a fee). Fellow hackers can communicate with me for free. If you wish to send me a public key message, my public key is included as COLSTON.PUB. My name is listed as Colston, C. David 05-30-1992 Key# 3,667,255. Use the QPK Menu to add it to KEYLIST.PUB after you have generated you own public key. The author of this program makes no warranties about it's performance. The program is not heavily error trapped, so you could make it "blow up". Any blow up would not compromise any message that you wish to send, however, at most it will merely not send the message or garble it beyond all recognition. Of that I have made very sure, but you can always tell the computer to do something impossible (such as request files which are no where to be found). Yes, I error trapped for that, but after 10 years of writing computer programs, I've learned that people can always surprise a programmer and find a way to do something he/she never conceived. ABOUT THE SOURCE CODE As I have already stated the source code is in QUICK BASIC 7.1. I wrote it in basic to prove how fast the public key decryption is compared to other methods. It also will hopefully end the joke about a "math pack" written in basic. This code is not very neat, I have not had time to go back and make every routine consistent from module to module. It is also not heavily remarked. If you have questions please feel free to get in touch with me. Big numbers in Q.P.K. are treated as long integer arrays, but only part of the bits in each member of the array are used. The routines assume (in most cases) that an incoming array represents a large number in base 4096 (2^12). In other words, if the number represented is 4096 and the array is A&(), then A&(2) = 1 and A&(1) =0. 4097 would be A&(2) = 1 and A&(1) = 1. If you think naturally in base 10 like most people, then you could place the number in the array in groups of three base 10 digits. (Think of each group of three digits as being separated by a comma.) Thus 9,123,746 in base 10 can be placed in the array as A&(3) = 9, A&(2) = 123, A&(1) = 746. You may then call the convert base routine: ABytes%=3 OldBase% = 1000 NewBase% = 4096 ConvertBase A&(), ABytes%, OldBase%, NewBase% This will convert the array to base 4096. The array would return as: A&(3) = 0, A&(2) = 2227, A&(1) = 1954. ABytes% would return as 2. You may then use any other math routine in the source code. I have included routines that add, subtract, multiply, divide, square root, modulo, exponentiate modulo, increment (add one), decrement (subtract one), find the multiplicative inverse of two big numbers, do Chinese remainder, covert the base, display a number in base 10, and find the square of x in a way that is 40% faster than multiplying X * X (Thank you, Joel Benston!). QPK routines are set up to "crunch" number up to 2 ^ 2070, but you may change the dimension statements to A&(256) and it should handle 2 ^ 3072. To give you some idea how big such numbers are, 2 ^ 1024 has about 309 decimal digits and 2 ^ 3072 would have about 927 decimal digits! ABOUT PUBLIC KEY PATENTS It is my firm belief that everything which is contained in the program is in the public domain, was developed by me, or use of an idea by conceived by someone else has been granted to me by appropriate authority. It is clear that this is NOT the RSA public key. RSA uses exponentiation modulo a number to achieve a public key decryption AND Ron Rivest has decried Rabin's squares modulo N for years. As I've said before, I think it's entirely mine, but, if it's not, it's much closer to RABIN than RSA. When Phil Zimmermann came out with P.G.P. last year, many people refused to use it for fear of violation of patent law. This program is not in violation of any law of which I am aware. One final note. This program is not compatible with any other program on the market or which is widely used, including P.G.P. by Phillip Zimmerman. You must give a copy of Q.P.K. to anyone you wish to communicate with. ABOUT Q.P.K. SPEED This program was compiled to be used even by a 8086 machine. You may recompile far any higher chip, if you wish. If you do not recompile all modules to stand alone files, you must use your own version of BRT71EFR.EXE to assure that the program will perform adequately. The program does FIVE secret key decryption for a 512 bit public key in about 8 seconds on an 8086 machine. It is algorithmically twenty times faster than R.S.A. decrypts from conventional key. I think that it can be optimized to be even faster. Even though Q.P.K. is fast. It is only as fast as your computer. The conventional key routine will encrypt and decrypt at about 10 to 20 characters per second on an 8086 machine (AFTER THE SET UP AND DEPENDING ON KEY SIZE). It will be six times faster on an 80286 and faster still on higher level chips. PUBLIC/SECRET KEY GENERATION TIMES FOR AN 8086 THE FOLLOWING TIMES ARE AVERAGE BUT MAY VARY WILDLY: 512 bit key - 45 minutes. 768 bit key - 2 hours. 1024 bit key - 6 hours. An 80286 will divide these times by a factor of 6. I have not tried this on an 80386 or 80486 machine. If you have a copy of QUICK BASIC 7.1 and wish more speed, the recompile the source code accordingly. It was compiled for the lowest common denominator, an 8086. SPECIAL THANKS (I.O.U.) O. Joel Benston, Charlie Merritt, and John Ewbank, the original public key encoders for P.C. Many of their concepts are in Q.P.K., especially Joel. Thanks to Phil Zimmermann for moral support! In addition, I wish to thank Euclid, Fermat, Gauss, Wilson, Euler, Jacobi, Rabin, and Williams for inspiration. C. David Colston (Colston and Associates, Inc.) 05-31-92 O.K. to post!