Click for homepage
← SpellMaster
← Algorithm
  
Python →
  
3. SpellMaster in BBC BASIC
Paul Reuvers — 3 August 2022

The third working simulator was made by Paul Reuvers (Crypto Museum) and is written in BBC BASIC on a RISC OS computer. Paul is a programmer in The Netherlands and writes software in C, BASIC and ARM Assembler. As the C-version of the SpellMaster simulator was already done, he wanted to add a BASIC variant as an extra flavour. Paul had already reconstructed the translation table at the start of the challenge, but had difficulty getting the calculation of the key to work. However, with working examples in Phyton and C, this appeared to be a piece of cake.

The main problem was that BBC BASIC does not have the concept of signed 8-bit variables (bytes). Instead these had to be simulated in a 32-bit integer, just like in the Phyton-version of the simulator. Like with the C-implementation, the standard modulo function (MOD) could not be used — it cannot cope with negatige values — and had to be replaced by a tailored function.

Download
BBC BASIC code
     
     REM > SpellMaster
     REM
     REM  SpellMaster encryption simulator in BBC BASIC
     REM  Version 1.00  (03 Aug 2022)
     REM  Crypto Museum, Paul Reuvers
     REM
     REM  Requires !Reporter to run.
     
     ON ERROR PROCerror : END
     
     CODEWORDSIZE = 8
     DIM CodeWord% CODEWORDSIZE + 1
     
     Alphabet$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-?"
     Enc$      = "HOWASMJRNEDGBXKTCQPUIYFZLV[\"
     Dec$      = "                            "
     
     PROCcreate_dec
     
     *report
     s$ = FN_enc("AAAAAAAA", "AAAAAAAAAA")
     s$ = FN_dec("AAAAAAAA", s$)
     
     *report
     s$ = FN_enc("CATS", "DOGSDOGSDOGSDOGS")
     s$ = FN_dec("CATS", s$)
     
     END
     
     
     
     DEF FN_enc(key$, pt$)
       LOCAL i%, j%, k%, key%, r%, ct$, m%, m$
     
       PROCexpand_key(CodeWord%, key$)
     
       FOR i% = 1 TO LEN(pt$)
         m% = INSTR(Alphabet$, MID$(pt$, i%, 1))
         m$ = MID$(Enc$, m%, 1)
         m% = ASC(m$) - 65
     
         REM calculate key
         key% = 0
         FOR j% = 0 TO CODEWORDSIZE - 1
           key% += (CodeWord%?j%) - 65
           IF key% < -128 THEN key% += 256
           IF key% >= 128 THEN key% -= 256
         NEXT
         key% = FNmod(key%, 28)
     
         REM apply key
         r% = FNmod(key% - m%, 28)
         ct$ += MID$(Alphabet$, r% + 1, 1)
     
         REM modify key
         FOR j% = 1 TO CODEWORDSIZE - 1
           CodeWord%?(j%-1) = CodeWord%?j%
         NEXT
         CodeWord%?(CODEWORDSIZE - 1) = FNmod(key% + m%, 28)
       NEXT
     
       *report Encoding: key$ pt$ "->" ct$
     
     =ct$
     
     
     
     DEF FN_dec(key$, ct$)
       LOCAL i%, j%, k%, key%, r%, pt$, m%, m$
     
       PROCexpand_key(CodeWord%, key$)
     
       FOR i% = 1 TO LEN(ct$)
         m% = ASC(MID$(ct$, i%, 1)) - 65
         IF m% = -2 THEN m% = 27
         IF m% = -20 THEN m% = 26
     
         REM calculate key
         key% = 0
         FOR j% = 0 TO CODEWORDSIZE - 1
           key% += (CodeWord%?j%) - 65
           IF key% < -128 THEN key% += 256
           IF key% >= 128 THEN key% -= 256
         NEXT
         key% = FNmod(key%, 28)
     
         REM apply key
         r% = FNmod(key% - m%, 28)
         pt$ += MID$(Dec$, r% + 1, 1)
     
         REM modify key
         FOR j% = 1 TO CODEWORDSIZE - 1
           CodeWord%?(j%-1) = CodeWord%?j%
         NEXT
         CodeWord%?(CODEWORDSIZE - 1) = FNmod(key% + r%, 28)
       NEXT
     
       *report Decoding: key$ pt$ "<-" ct$
     
     =pt$
     
     
     
     DEF PROCcreate_dec
       LOCAL i%
       Dec$ = STRING$(28, " ")
       FOR i% = 1 TO 28
         MID$(Dec$, ASC(MID$(Enc$, i%, 1)) - 64, 1) = CHR$(i% + 64)
       NEXT
     ENDPROC
     
     
     
     DEF PROCexpand_key(loc%, key$)
       LOCAL i%, j%, c%, len%
       len% = LEN(key$)
       FOR i% = 0 TO CODEWORDSIZE - 1
         c% = ASC(MID$(key$, j%+1, 1)) AND NOT 32
         IF c% >= 65 AND c% <= 90 THEN
           loc%?i% = c%
         ELSE
           ERROR 1,"Illegal character in keyword"
         ENDIF
         j% += 1
         IF j% >= len% THEN j% = 0
       NEXT
     ENDPROC
     
     
     
     
     DEF FNmod(val%, mod%)
       IF val% > 0 THEN =val% MOD mod%
       WHILE val% < 0
         val% += mod%
       ENDWHILE
     =val%
     
     
     
     DEF PROCerror
       LOCAL error$
       error$ = REPORT$+" at line " + STR$(ERL)
       *report error$
     ENDPROC
     
    
Further information
Any links shown in red are currently unavailable. If you like the information on this website, why not make a donation?
© Crypto Museum. Created: Wednesday 03 August 2022. Last changed: Friday, 05 August 2022 - 06:46 CET.
Click for homepage