I am sorry if this exists already...
....I also want to share this the right way
If this violates any rules tell me right away and I will correct it.
This is a part of a larger project that is inspired
by so much of the TI Community that I still do not
know how to release it, but the only part that
may matter to the rest of you all is the
crude port of RabbitSign I put together.
This code is based on the RabbitSign source.
The modifications to the multiplication routines
and Z80 speed optimizations are my own.
Signing on 83+ is about 5 minutes, 1 and some
40 seconds on the 84+ if set to 15 mhz.
This is only tested for the shareware 0104 key.
My ultimate dream for this code
is that the author of the Axe Parser would use
it to allow his program to sign flash apps on calc..
but as it is about 2k of code, would probably
need to be added as a plugin...appvar maybe...
I will release a stand-alone as the source here
is not buildable without removal of references
to the bigger project, but a good coder could
knock that out quickly, this is more just in
case someone wants to add support themselves
yes, I wrote it in Mimas..but modded for spasm..
If you use it to write a signing feature a mention of
Rovax would be desired, but it is inspired by Rabbit
Sign, so it is only fair it be mentioned too...
If there is a lot of interest in this then
I will push myself to get a stand-alone build
in the next few weeks...but it would be of little use
besides proving the signing code works...
Signature verification is built in though...
Code:
....I also want to share this the right way
If this violates any rules tell me right away and I will correct it.
This is a part of a larger project that is inspired
by so much of the TI Community that I still do not
know how to release it, but the only part that
may matter to the rest of you all is the
crude port of RabbitSign I put together.
This code is based on the RabbitSign source.
The modifications to the multiplication routines
and Z80 speed optimizations are my own.
Signing on 83+ is about 5 minutes, 1 and some
40 seconds on the 84+ if set to 15 mhz.
This is only tested for the shareware 0104 key.
My ultimate dream for this code
is that the author of the Axe Parser would use
it to allow his program to sign flash apps on calc..
but as it is about 2k of code, would probably
need to be added as a plugin...appvar maybe...
I will release a stand-alone as the source here
is not buildable without removal of references
to the bigger project, but a good coder could
knock that out quickly, this is more just in
case someone wants to add support themselves
yes, I wrote it in Mimas..but modded for spasm..
If you use it to write a signing feature a mention of
Rovax would be desired, but it is inspired by Rabbit
Sign, so it is only fair it be mentioned too...
If there is a lot of interest in this then
I will push myself to get a stand-alone build
in the next few weeks...but it would be of little use
besides proving the signing code works...
Signature verification is built in though...
Code:
;#SECTION "MAIN", CODE
DoRSign:
#if RSIGN
bit ISVAT, (iy + asm_Flag1)
ret z
call SetFst
; 40H+3+4+1 PAD
ld hl, 48h
B_CALL _EnoughMem
ret c
call CalcSelectedVAR
ld hl, Unload
push hl
; Zero Buffers
ld hl, MultBuf
ld bc, VarEnd - MultBuf - 1
call clearMem
ld (SaveSP), sp
B_CALL _ChkFindSym
ret c
ex de, hl
ld (APPLoc), hl
ld e, (hl)
inc hl
ld d, (hl)
inc hl
ld (APPSize), de
; Sanity check start 800F
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
ld bc, 0F80h
; CF=0
sbc hl, bc
jp nz, InvalidHeader
;
call myGrBufClr
call PenSetupCS2
db 1, 0
ld hl, SignDesc
call myVPutSCpy
call GetQCSC
ret nz
ld hl, UpdateTxt
call myVnewline
call myVPutSCpy
call SizeFix
call SetSize
jp c, InvalidHeader2
; HL is start
ld hl, (APPLoc)
inc hl
inc hl
; 2nd sanity
ld bc, (APPSize)
; Calculate MD5
B_CALL _MD5Init
B_CALL _MD5Update
B_CALL _MD5Final
B_CALL 80A5h
; Copy MD5 transform 2
ld hl, 8292h
ld a, 01h
ld de, TransKeySP
ld (de), a
inc de
ld bc, 16
ldir
ld bc, 40h
ld h, d
ld l, e
inc de
ld (hl), 0
ldir
call Encrypt
call findVATItems
ld a, 0
ret
Failed:
ld hl, SignFTxt
_:
call CallPuts
call GetQCSC
EEnd:
ld sp, (SaveSP)
ld iy, flags
ret
#else
ret
#endif
;#SECTION "ENCRYPT", CODE
#if RSIGN
; Result in Buffer1
Encrypt:
#if 0
ld hl, Md5Txt
call myVnewlinePut
ld de, TransKeySP + 1
call IncPCol
call ShowHash
ld de, TransKeySP + 9
call ShowHash
#endif
call myVnewline
ld hl, TGTxt
call myVPutSCpy
call myVnewline
call GetLegP
; If Leg=1 false,+1
call l_Zrochk
ld a, 1
jr c, +_
xor a
_:
push af
call GetLegQ
; If Leg=1 ,+2
call l_Zrochk
pop de
ld a, d
jr c, +_
add a, 2
_:
ld (TForm), a
call ShowTF
call ApplyTF
call myVnewline
;
call GetSQRr
ld hl, Buffer1
ld de, SQRr
ld bc, 40h
ldir
;
call GetSQRs
ld hl, Buffer1
ld de, SQRs
ld bc, 40h
ldir
; Use These 2 IFs to change
; The Root Number
#if 0
ld hl, Key0104P + 1
ld de, SQRr
ld b, 40h
or a
_:
ld a, (de)
ld c, a
ld a, (hl)
sbc a, c
ld (de), a
inc de
inc hl
djnz -_
#endif
; root 2
#if 0
ld hl, Key0104Q + 1
ld de, SQRs
ld b, 40h
or a
_:
ld a, (de)
ld c, a
ld a, (hl)
sbc a, c
ld (de), a
inc hl
inc de
djnz -_
#endif
;
ld de, res
ld hl, SQRr
ld bc, 40h
ldir
; DO ABS(r-s),must be pos
ld de, res
ld hl, SQRs
ld b, 40h
or a
_:
ld a, (de)
sbc a, (hl)
ld (de), a
inc de
inc hl
djnz -_
jr nc, l_doqinv
; calc 1's comp
ld hl, res
push hl
ld b, 40h
_:
ld a, (hl)
cpl
ld (hl), a
inc hl
djnz -_
; INC to make 2's comp
; pop res to HL
pop hl
_:
inc (hl)
inc hl
jr z, -_
;
l_doqinv:
ld hl, res
ld de, Key0104QINV
ld bc, 4040h
call XMul
; Do A mod P
ld hl, Key0104P
call DoMod
; Preserve result
ld hl, Buffer1
ld de, res
ld bc, 40h
ldir
; Do A times Q
ld hl, res
ld de, Key0104Q + 1
ld bc, 4040h
call XMul
; Do ADD of S to res
; Unsigned only...
ld hl, SQRs
ld de, MultBuf
ld b, 40h
or a
_:
ld a, (de)
sbc a, (hl)
ld (de), a
inc de
inc hl
djnz -_
; Check if Good
ld hl, MultBuf
ld de, res
ld bc, 40h
ldir
; A^2 mod N
ld hl, res
ld de, res
ld bc, 4040h
call XMul
ld hl, Key0104N
call DoMod
ld hl, Buffer1
ld de, TransKeySP
ld b, 40h
_:
ld a, (de)
cp (hl)
jp nz, Failed
inc de
inc hl
djnz -_
IsGood:
call AddSig
jp SuccessSPop
#endif
;#SECTION "Keys", DATA
#if RSIGN
Key0104N:
db 41h
db 0ADh, 24h, 31h, 0DAh, 22h, 97h, 0E4h, 17h
db 5Eh, 0ACh, 61h, 0A3h, 15h, 4Fh, 0A3h, 0D8h
db 47h, 11h, 57h, 94h, 0DDh, 33h, 0Ah, 0B7h
db 0FFh, 36h, 0BAh, 59h, 0FEh, 0DAh, 19h, 5Fh
db 0EAh, 7Ch, 16h, 74h, 3Bh, 0D7h, 0BCh, 0EDh
db 8Ah, 0Dh, 0A8h, 85h, 0E5h, 0E5h, 0C3h, 4Dh
db 5Bh, 0F2h, 0Dh, 0Ah, 0B3h, 0EFh, 91h, 81h
db 0EDh, 39h, 0BAh, 2Ch, 4Dh, 89h, 8Eh, 87h
db 0, 0, 0
Key0104P:
db 20h
db 5Bh, 2Eh, 54h, 0E9h, 0B5h, 0C1h, 0FEh, 26h
db 0CEh, 93h, 26h, 14h, 78h, 0D3h, 87h, 3Fh
db 3Fh, 0C4h, 1Bh, 0FFh, 0F1h, 0F5h, 0F9h, 34h
db 0D7h, 0A5h, 79h, 3Ah, 43h, 0C1h, 0C2h, 1Ch
dw 0, 0, 0, 0, 0, 0, 0, 0
dw 0, 0, 0, 0, 0, 0, 0, 0, 0
Key0104Q:
db 21h
db 97h, 0F7h, 70h, 7Bh, 94h, 07h, 9Bh, 73h
db 85h, 87h, 20h, 0BFh, 6Dh, 49h, 09h, 0ABh
db 3Bh, 0EDh, 0A1h, 0BAh, 9Bh, 93h, 11h, 2Bh
db 04h, 13h, 40h, 0A1h, 6Eh, 0D5h, 97h, 0B6h
db 04h
dw 0, 0, 0, 0, 0, 0, 0, 0
dw 0, 0, 0, 0, 0, 0, 0, 0, 0
Key0104QINV:
db 0A3h, 82h, 96h, 0AFh
db 3Dh, 0DDh, 9Bh, 94h
db 0AEh, 0A0h, 2Fh, 2Ch
db 0E3h, 8Bh, 0CDh, 0D9h
;
db 0C9h, 11h, 75h, 4Fh
db 00h, 0E4h, 0DFh, 47h
db 38h, 0CDh, 98h, 16h
db 47h, 0F5h, 2Bh, 0Fh
;
dw 0, 0, 0, 0, 0, 0, 0, 0
dw 0, 0, 0, 0, 0, 0, 0, 0
dw 0, 0
#endif
;#SECTION "AMODN", CODE
#if RSIGN
SetModKey:
; HL Points to Key Length
ld a, (hl)
inc hl
ld (CurMKey3), a
dec a
ld b, 0
ld c, a
ld (CurMKey1), hl
add hl, bc
ld (CurMKey2), hl
; Reset test registers
ld a, 61h
ld (CurpMODa1), a
ld hl, Buffer1
ld (CurpMODa2), hl
add hl, bc
ld (OP2), hl
ret
DoMod:
call SetModKey
AMod:
; Mult routine does clearing
; Num of bytes to test
ld a, (CurpMODa1)
ld iyh, a
; Test register start address
ld ix, (CurpMODa2)
; Calc shifts A/8
ld a, (CurMKey3)
rrca
rrca
rrca
and 1Fh
ld (OP2 + 2), a
;
AModSFT:
dec ix
ld a, (ix + 0)
ld (ix + 0), 0
ld (Buffer1 - 1), a
ld c, 8
BufLP1:
ld hl, Buffer1 - 1
ld a, (OP2 + 2)
ld b, a
_:
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
inc hl
djnz -_
rl (hl)
inc hl
rl (hl)
jr c, DoSub9
; CMP (HL) to (DE)
ld a, (CurMKey3)
ld b, a
ld de, (OP2)
ld hl, (CurMKey2)
_:
ld a, (de)
cp (hl)
jr c, l_EEnd2
jr z, l_nnx
jr DoSub9
l_nnx:
dec hl
dec de
djnz -_
DoSub9:
; Carry is never set here
ld a, (CurMKey3)
ld b, a
ld de, Buffer1
ld hl, (CurMKey1)
_:
ld a, (de)
sbc a, (hl)
ld (de), a
inc de
inc hl
djnz -_
l_EEnd2:
dec c
jp nz, BufLP1
;
or a
dec iyh
jp nz, AModSFT
ret
#endif
;#SECTION "TempSpc", DATA
#if RSIGN
; assert VarEnd - MultBuf < 768
MultBuf equ saveSScreen
; This size is crucial 61H
Buffer1 equ MultBuf + 61h
EXPBUF equ Buffer1 + 44h
TEMP equ EXPBUF + 24h
BaseBuf equ TEMP + 42h
SQRr equ BaseBuf + 42h
SQRs equ SQRr + 42h
res equ SQRs + 42h
CurpMODa1 equ res + 42h
APPSize equ CurpMODa1 + 1
APPLoc equ APPSize + 2
TForm equ APPLoc + 2
SaveSP equ TForm + 1
CurpMODa2 equ SaveSP + 2
CurMKey1 equ CurpMODa2 + 2
CurMKey2 equ CurMKey1 + 2
CurMKey3 equ CurMKey2 + 2
CurEXP1 equ CurMKey3 + 1
CurEXP2 equ CurEXP1 + 2
CurpMULT1 equ CurEXP2 + 2
DotCheck equ CurpMULT1 + 2
VarEnd equ DotCheck + 1
#endif
;#SECTION "Mult", CODE
#if RSIGN
; IX=Buffer
; DE =multiplier
; B=size of multiplier
; HL=multiplicand
; C=size of multiplicand
; Disable Interrupts
XMul:
ld ix, MultBuf
ld iyh, b
ld iyl, c
; XOR A
push hl
;
#if 0
push ix
pop hl
;
ld (hl), a
inc hl
djnz _clear1
ld b, c
_clear2:
ld (hl), a
inc hl
djnz _clear2
#else
; use SP zero test registers
ld hl, 0
ld b, h
ld c, l
add hl, sp
ld sp, Buffer1 + 41h
; 60H+40H+2
ld a, 6 + 4
lllp:
push bc
push bc
push bc
push bc
push bc
push bc
push bc
push bc
dec a
jp nz, lllp
push bc
ld sp, hl
#endif
;
;
pop hl
;
_loopA:
ld c, (hl)
; Loop counter
ld a, iyh
push hl
push de
ld (OP3), sp
ld sp, ix
_loopB:
; save counter
ex af, af'
ld a, (de)
ld h, a
; CALL mul_hc
ld l, 0
ld b, l
; 1
add hl, hl
jr nc, +_
add hl, bc
_:
; 2
add hl, hl
jr nc, +_
add hl, bc
_:
; 3
add hl, hl
jr nc, +_
add hl, bc
_:
; 4
add hl, hl
jr nc, +_
add hl, bc
_:
; 5
add hl, hl
jr nc, +_
add hl, bc
_:
; 6
add hl, hl
jr nc, +_
add hl, bc
_:
; 7
add hl, hl
jr nc, +_
add hl, bc
_:
; 8
add hl, hl
jr nc, +_
add hl, bc
_:
ld a, c
pop bc
add hl, bc
push hl
ld c, a
jr nc, _endB
ld hl, 2
add hl, sp
_Cyloop:
inc (hl)
inc hl
jr z, _Cyloop
_endB:
inc sp
inc de
ex af, af'
dec a
jr nz, _loopB
ld sp, (OP3)
pop de
pop hl
inc hl
inc ix
dec iyl
jp nz, _loopA
ret
#endif
;#SECTION "Transfor", CODE
#if RSIGN
; -2X,-X,X,2X = 0,1,2,3
TransKeySP equ statVars + 256
ApplyTF:
ld a, (TForm)
cp 4
ret nc
cp 2
ret z
cp 3
jr z, TFTimes2
or a
call z, TFTimes2
; Else 1 or 0 is -2x or -x
ld hl, TransKeySP
ld de, Key0104N + 1
ld b, 40h
or a
_:
ld a, (de)
sbc a, (hl)
ld (hl), a
inc de
inc hl
djnz -_
ret
TFTimes2:
ld b, 41h
ld hl, TransKeySP
or a
_:
rl (hl)
inc hl
djnz -_
ret
#endif
;#SECTION "MODEXP", CODE
#if RSIGN
; Legendre = a^(p-1)/2
GetLegP:
ld hl, Key0104P
jr +_
GetLegQ:
ld hl, Key0104Q
; Set up EXP -1,/2
_:
ld bc, 0FF01h
jr CustEXP
; Square Root = a^(p+1)/4
GetSQRr:
ld hl, Key0104P
jr +_
GetSQRs:
ld hl, Key0104Q
_:
; Set up EXP +1,/4
ld bc, 0102h
CustEXP:
; Set up Exponent
ld (CurEXP2), bc
call SetModKey
; Reset 1st mult
ld hl, 4040h
ld (CurpMULT1), hl
; Setup TEMP to 1
ld hl, TEMP
ld (hl), 1
inc hl
ld (hl), 00h
ld d, h
ld e, l
inc de
ld bc, 40h
ldir
; Setup Exp Buffer 22H
ld hl, (CurMKey1)
ld de, EXPBUF
ld bc, 21h
ldir
ld hl, EXPBUF
ld bc, (CurEXP2)
ld a, (hl)
add a, b
ld (hl), a
; Add cause carry?
or a
; C Has DIV
DoEXP:
ld b, 22h
ld hl, EXPBUF + 22h
_:
dec hl
rr (hl)
djnz -_
dec c
jr nz, DoEXP
; Setup Base Buffer
ld hl, TransKeySP
ld de, BaseBuf
ld bc, 40h
ldir
; Do Mod Exp #256 +8
; LD B,8
; LD C,2
ld bc, 8 * 256 + 2
DoQMod:
push bc
in a, (4)
bit 3, a
jp z, OnBreakPop
;
ld iy, flags
push af
call DoDot
pop af
or a
;
ld hl, EXPBUF + 22h
ld b, 22h / 2
_:
dec hl
rr (hl)
dec hl
rr (hl)
djnz -_
jr nc, +_
; Test LSb of exponent
; Result is 80H (or 42H)
ld hl, BaseBuf
ld de, TEMP
ld bc, (CurpMULT1)
call XMul
call AMod
; Mult Base and temp
; Prod Mod P To TEMP
ld hl, Buffer1
ld de, TEMP
ld bc, 40h
ldir
_:
; Setup base#2 squared
; Result is 40H
ld hl, BaseBuf
ld d, h
ld e, l
ld bc, (CurpMULT1)
call XMul
; Mod P The Base
call AMod
; Buffer1 has new base
; Reduce mod factor sz
; 21H+21H
ld a, (CurpMODa1)
cp 42h
jr z, +_
ld a, 42h
ld (CurpMODa1), a
ld hl, MultBuf + 42h
ld (CurpMODa2), hl
; Reduce mult factor sz
ld a, (CurMKey3)
ld h, a
ld l, a
ld (CurpMULT1), hl
_:
;
ld hl, Buffer1
ld de, BaseBuf
ld bc, 40h
ldir
;
pop bc
djnz DoQMod
dec c
jr nz, DoQMod
;
ld hl, TEMP
ld de, Buffer1
ld bc, 40h
ldir
ret
l_EEnd:
pop bc
ret
#endif
;#SECTION "Utils", CODE
#if RSIGN
l_Zrochk:
ld hl, Buffer1
ld a, 1
cp (hl)
scf
ret nz
ld b, 3Fh
xor a
_:
inc hl
or (hl)
djnz -_
ret z
scf
ret
#if 0
ShowHash:
ld b, 8
call myVnewline
call DecPCol
l_LP1:
ld a, (de)
inc de
push bc
push de
ld d, a
rrca
rrca
rrca
rrca
and 0Fh
cp 10
jr c, +_
add a, 7
_:
add a, 30h
call myVPutC
call DecPCol
ld a, d
and 0Fh
cp 10
jr c, +_
add a, 7
_:
add a, 30h
call myVPutC
pop de
pop bc
djnz l_LP1
ret
#endif
ShowTF:
ld hl, TFTxt
call CallPuts
ld a, (TForm)
add a, 30h
jr CallPutC
SizeFix:
; Check lsB of size 55 Mod 64
ld a, (APPSize)
and 63
cp 55
ret nz
; increase size byte
; used by variable
ld hl, (APPLoc)
inc (hl)
inc hl
inc hl
; HL points to start of var
ld bc, (APPSize)
add hl, bc
; HL Points to end of file
push hl
ex de, hl
ld hl, 1
B_CALL _InsertMem
pop hl
; Zero out padded byte
ld (hl), 0
ld hl, PadTxt
; jr CallPuts
CallPuts:
ld iy, flags
call myVnewline
jp myVPutSCpy
CallPutC:
ld iy, flags
jp myVPutCcpy
SetSize:
ld hl, (APPSize)
ld bc, -6
add hl, bc
ex de, hl
; DE is size field
ld hl, (APPLoc)
ld bc, 6
add hl, bc
; HL is 6 into file
ld (hl), d
inc hl
ld (hl), e
inc hl
; Write size minus 6 into SZ
; Update key field to 0104
ld a, 12h
ld bc, 10
cpir
scf
ret po
ld (hl), 1
inc hl
ld (hl), 4
or a
ret
AddSig:
ld hl, (APPLoc)
ld c, (hl)
inc hl
ld b, (hl)
inc hl
; Skip size Bytes
add hl, bc
ex de, hl
ld hl, 40h + 3 + 4
; DE Points to end of file
push de
; HL Is size added
push hl
B_CALL _InsertMem
pop de
; DE Is size
ld hl, (APPSize)
add hl, de
ex de, hl
ld hl, (APPLoc)
ld (hl), e
inc hl
ld (hl), d
; Size bytes are updated
; HL is end of file
pop hl
ld (hl), 02h
inc hl
ld (hl), 2Dh
inc hl
ld (hl), 40h
inc hl
ex de, hl
; Copy signature
ld hl, res
ld bc, 40h
ldir
ex de, hl
; Transform Type
ld a, (TForm)
or a
jr nz, +_
ld b, 3
ld (hl), 0
l_llp6:
inc hl
ld (hl), 0FFh
djnz l_llp6
ret
_:
ld (hl), 1
inc hl
ld (hl), a
ld b, 2
jr l_llp6
#endif
;#SECTION "Utils2", CODE
#if RSIGN
DoDot:
ld a, (DotCheck)
inc a
ld (DotCheck), a
cp 11
ret nz
xor a
ld (DotCheck), a
ld a, '.'
jp CallPutC
#endif
;#SECTION "Strings", CODE
#if RSIGN
OnBreakPop:
in a, (4)
bit 3, a
jr z, OnBreakPop
call PopupCS5
dw OnBreakTxt
db 38, 17, 18
ld iy, flags
call GetQCSCNC
jp EEnd
SuccessSPop:
call PopupCS5
dw SuccTxt
db 38, 21, 21
ld iy, flags
jp GetQCSCNC
InvalidHeader2:
call PopupCS5
dw InvHDTxt2
db 38, 24, 21
jp GetQCSCNC
InvalidHeader:
call PopupCS5
dw InvHDTxt
db 38, 23, 19
Unload:
call GetQCSCNC
jp findVATItems
#endif
;#SECTION "StringDT", DATA
#if RSIGN
#if 0
Md5Txt:
db "App MD5 Hash to Sign:", 0
#endif
UpdateTxt:
db "Updating Size and Key Fields", 0
PadTxt:
db "Size is 55 Mod 64,Pad!", 0
OnBreakTxt:
db "Calculation Halted", 0
db "Signature Invalid", 0
SignFTxt:
db "Failed Validation!", 0
TFTxt:
db "Signing VAR using TF: ", 0
TGTxt:
db "Calculating Transform:", 0
SignDesc:
db "Sign Var Freeware? (Enter)", 0
SuccTxt:
db "Signature Good!", 0
db "Appended to Var", 0
InvHDTxt2:
db "Invalid Header", 0
db "Missing Key Field", 0
InvHDTxt:
db "Invalid Header", 0
db "Must Begin $800F", 0
#endif