'Subject: Cryptography, exponential encryption with salt.
'Author : Sjoerd.J.Schaper
'Date   : 03-13-2005
'Code   : QuickBasic, PDS, VBdos, FreeBasic
REM $LANG: "qb"
REM $INCLUDE: 'largeint.bi'
DECLARE SUB readkey (p, g$)
'read base 64 data
CONST m = 0, e = 1, N = 2
t = LargeInit(N, "encoder")
DIM pc AS LONG, pp AS LONG
DIM byt AS STRING * 1, b4 AS STRING * 4
DIM g(2) AS STRING, wdir AS STRING
wdir = SPACE$(64): Work wdir '         working directory
CLS : tim# = TIMER

begin:
LOCATE 1, 1
PRINT "   +--------------------------------------------------+"
PRINT "   |  input: filenames for                            |"
PRINT "   |  public key, message and ciphertext, 0 to exit.  |"
PRINT "   |                                                  |"
PRINT "   +--------------------------------------------------+"
LOCATE 4, 7: INPUT ; "k"; g(0)
IF INSTR(g(0), "'") THEN GOTO begin
IF g(0) = "" OR g(0) = "0" THEN GOTO eind
k = FREEFILE
OPEN wdir + g(0) FOR INPUT AS k
   FOR t = 0 TO 2
      INPUT #k, g(t) '                 split modulus N & public exp.
   NEXT t
CLOSE k
'
readkey e, g(2)
readkey N, g(0) + g(1)
k = -INT(-Bitl(N) / 8) '               octet length(N)
IF k < 10 THEN
   LOCATE 7, 1: Prints " modulus too small", 1
   GOTO eind
END IF
'
INPUT ; " m"; g(0): Pfile = FREEFILE
OPEN wdir + g(0) FOR BINARY AS Pfile ' plaintext
INPUT " c"; g(0): Cfile = FREEFILE
OPEN wdir + g(0) FOR BINARY AS Cfile ' cipher

pp = LOF(Pfile)
b4 = MKL$(pp * 512 + k)
PUT #Cfile, 1, b4 '                    write len(Pfile), len(N)
ks = k - 9 '                           seasoning space
s = -INT(-pp / ks)

LOCATE 7, 1
Prints " record length: " + STR$(ks), 1
Prints " total records: " + STR$(s), 1

pp = 1: pc = 5 '                       initial positions
FOR r = 1 TO s
   LOCATE 10, 2: PRINT "record "; r;
   '
   Letf m, 0
   pp = pp + ks
   FOR t = 1 TO ks '                   convert message to base MB
      GET #Pfile, pp - t, byt
      Inc m, ASC(byt): Lsft m, 8
   NEXT t
   Lsft m, 56: Rndf t0, 64
   Boolf m, t0, 3 '                    paste in 8-byte salt
   '
   Modpwr m, e, N '                    cipher m^ e Mod N
   '
   pc = pc + k
   FOR t = 1 TO k '                    write cipher octets
      byt = CHR$(Mp2(m, 256))
      PUT #Cfile, pc - t, byt
      Rsft m, 8
   NEXT t
NEXT r

CLOSE Cfile
CLOSE Pfile
GOTO begin

eind:
LOCATE 10, 1
g(0) = STR$(CSNG(TIMER - tim#))
Prints " Timer:" + g(0) + " s", 0
CALL Term
SYSTEM

SUB readkey (p, g$)
b64$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
   '
   IF RIGHT$(g$, 1) = "=" THEN i = 1
   IF RIGHT$(g$, 2) = "==" THEN i = 2
   Letf p, 0: k = LEN(g$) - i
   FOR t = 1 TO k '                    base-64 to largeint
      j = INSTR(b64$, MID$(g$, t, 1))
      IF j > 0 THEN Inc p, j - 1
      IF t < k THEN Lsft p, 6
   NEXT t
   IF i > 0 THEN Rsft p, i * 2
END SUB

