    Rem Program to Register SDOS to a particular customer
    Rem Last Edit date: 8/14/81
    Rem This program should keep track of registered customers!
    Dim Randomizer$/:55,:a6,:0a,:9c,:e3,:57,:ac,:39/
    dim Temp$(50),Customer$(50)/"MAGICKEY"/
    dim in/1/,out/2/
    Rem "MAGICKEY" string initial value is purely a Red Herring
    Rem ****************************************************************
    Rem The Super-Secret SDOS key used to generate encrypt/decryption keys
    dim SDOSSecretKey$/:4c,:b0,:b7,:4e,:9b,:65,:72,:c9/
    Rem ****************************************************************
!
!   ****** Main Program starts here
!
RegisterSDOS:
    Print "Register SDOS to customer, V1.0"
    Print "Copyright (C) 1981 Software Dynamics"
    Print "This program must not leave the premises of Software Dynamics!"

Again:
    Input "Enter name of customer: " Customer$
    If len(Customer$)=0 or len(Customer$)>40
    then print "Customer name is illegal!"\goto again
    Rem pad with zeros
    For i=len(Customer$)+1 to 40 do Customer$[i]=0
    Let len(Customer$)=40
    Let Customer$=uppercase$(Customer$)
Stripblanks: Rem remove blanks
    Let I=Find(Customer$," ")
    If I>0
    then
        Rem remove the blank by shifting all bytes to right, left one place
        Right$(Customer$,I)=Right$(Customer$,I+1)
        Rem put zero byte on right end to fill gap
        Customer$[40]=0
        goto Stripblanks
    fi
Striptabs: Rem remove tab characters
    Let I=Find(Customer$,chr$(:9))
    If I>0
    then
        Rem remove the tab by shifting all bytes to right, left one place
        Right$(Customer$,I)=Right$(Customer$,I+1)
        Rem put zero byte on right end to fill gap
        Customer$[40]=0
        goto Striptabs
    fi
print "Canonical form is : >";Customer$;"<"

Rem Now Customer name is in Canonical form, uppercase with no blanks or tabs

AskSerialNumber: Rem get serial number of system that customer is using
    Print "CPU Serial Number:>****************<";
    For i=1 to 17 do print chr$(8);
    Input '' Temp$
    If len(Temp$)<>16 then AskSerialNumber
    For i=0 to 7
        If Error When Temp$[i+1]=Val(":" Cat Temp$[i*2+1,2])
        Then AskSerialNumber
    Next i

Rem We are ready to compute the Registration number.
Rem This is the cascaded encryption of SDOSSecretKey$,ROM serial number,...
Rem and the bytes of Canonical customer name.

    Call Encrypt(SDOSSecretKey$,Temp$) \ ! 1st step of cascade
    Call Encrypt(Temp$,Customer$[1,8]) \ ! 2nd step of cascade
    Call Encrypt(Customer$[1,8],Customer$[9,8]) \ ! 3rd step
    Call Encrypt(Customer$[9,8],Customer$[17,8]) \ ! 4th step
    Call Encrypt(Customer$[17,8],Customer$[25,8]) \ ! 5th step
    Call Encrypt(Customer$[25,8],Customer$[33,8]) \ ! 6th step
    Print "Registration code is: "
    Call DisplayKey(Customer$[33,8])
    Exit


Subroutine DisplayKey(DisplayKey$)
    For i=1 to 8 do print hex$(DisplayKey$[i])[4,2];
    Print
    Return Subroutine
End

Subroutine Encrypt(Key$,Data$)
    Rem This Subroutine Encrypts Data$ according to...
    Rem Ira B's Nasty Little Encryption Algorithm,
    Rem As Defined by the following code:
    Rem (This code is designed to be easy and relatively fast in assembler)
    Rem DEBUG ONLY Print "ENCRYPT: Encryption Key";\call displaykey(key$)
    Rem DEBUG ONLY Call DisplayKey(Data$)
    Rem Step 1. Make Most Significant byte depend on all 64 bits.
    Rem This step lets us get away with only 8-12 iterations, instead of 64.
    Temp=0
    For Byte=1 to 8 do temp=temp XOR Data$[Byte]
    Let Data$[1]=Temp
    Rem DEBUG ONLY Print "Step 1: ";\Call DisplayKey(data$)
    Rem Step 2. Now encrypt using MSB as encryption control bits
    For IterationCount=1 to 8+(Key$[8]&:3)
        If Data$[1]&:80
        Then
            Rem Print "Encrypt Step";
            Let Byte=8
            Let Temp=((Data$[1] XOR Key$[1])&:80)/128 \ ! "Encrypt" control bit
            Repeat
                Let Temp=((Data$[Byte] XOR Key$[Byte])**1)+Temp
                Let Data$[Byte]=Temp&:FF
                Let Temp=(Temp&:100)/256 \! Carry into Next byte
                Byte=Byte-1
            Unless Byte=0 End
        Else
            Rem Print "Randomize Step";
            Let Byte=8
            Let Temp=((Data$[1] XOR Key$[1])&:80)/128 \ ! "Encrypt" control bit
            Repeat
                Let Temp=((Data$[Byte] XOR Randomizer$[Byte])**1)+Temp
                Let Data$[Byte]=Temp&:FF
                Let Temp=(Temp&:100)/256 \! Carry into Next byte
                Byte=Byte-1
            Unless Byte=0 End
        Fi
        Rem DEBUG ONLY Print IterationCount;\Call DisplayKey(Data$)
    Next IterationCount
    Rem Step 3. Make Least Significant byte depend on all 64 bits.
    Rem This step makes Encrypt and Decrypt equally good at encrypting.
    Temp=0
    For Byte=1 to 8 do temp=temp XOR Data$[Byte]
    Let Data$[8]=Temp
    Rem DEBUG ONLY Print "Encrypt Final: ";\Call DisplayKey(data$)
    Return Subroutine
End

END
