i know it is a very old code...
i have tested now on win7 64bit with PB5.22 LTS (x86) .... (sorry i have no linux)
(works also with enabled unicode but you can use only the half characters in the message)
maybe some other can test the code and report errors ...
Code: Alles auswählen
EnableExplicit
;andi256
;PB4.60
;Length of digit in bits
#NN_DIGIT_BITS =32
#NN_HALF_DIGIT_BITS =16
;Length of digit in bytes
#NN_DIGIT_LEN =(#NN_DIGIT_BITS / 8)
;Maximum length in digits
#MAX_NN_DIGITS =128; =((#MAX_RSA_MODULUS_LEN + #NN_DIGIT_LEN - 1) / #NN_DIGIT_LEN + 1)
;Maximum digits
#MAX_NN_DIGIT = $ffffffff
#MAX_NN_HALF_DIGIT = $ffff
Structure LNG
l.l[#MAX_NN_DIGITS] ; ;Maximum digits #MAX_NN_DIGIT
EndStructure
Structure LNG_3
lng.LNG[3]
EndStructure
Procedure groesser(a,b)
!XOR eax,eax
!MOV ebx,[p.v_a]
!CMP ebx,[p.v_b]
!SETA al
ProcedureReturn
EndProcedure
Procedure groessergleich(a,b)
!XOR eax,eax
!MOV ebx,[p.v_a]
!CMP ebx,[p.v_b]
!SETAE al
ProcedureReturn
EndProcedure
Procedure div(a,b)
!MOV eax,[p.v_a]
!XOR edx,edx
!DIV dword [p.v_b]
ProcedureReturn
EndProcedure
;Assigns a = b.
;Lengths: a[digits], b[digits]
Procedure NN_Assign(*a.LNG,*b.LNG,digits)
Protected i.i
For i=0 To digits-1
*a\l[i]=*b\l[i]
Next i
EndProcedure
Procedure HIGH_HALF(x)
ProcedureReturn (x>>#NN_HALF_DIGIT_BITS)&#MAX_NN_HALF_DIGIT
EndProcedure
Procedure LOW_HALF(x)
ProcedureReturn x&#MAX_NN_HALF_DIGIT
EndProcedure
Procedure TO_HIGH_HALF(x)
ProcedureReturn x<<#NN_HALF_DIGIT_BITS
EndProcedure
Procedure DIGIT_2MSB(x)
ProcedureReturn (x>>(#NN_DIGIT_BITS-2))&3
EndProcedure
;Assigns a = 0.
;Lengths: a[digits].
Procedure NN_AssignZero(*a.LNG,digits)
Protected i.i
For i=0 To digits-1
*a\l[i]=0
Next i
EndProcedure
Procedure NN_ASSIGN_DIGIT(*a.LNG,b,digits)
NN_AssignZero (*a,digits)
*a\l[0]=b
EndProcedure
;Returns the significant length of a in digits.
;Lengths: a[digits]
Procedure NN_Digits(*a.LNG,digits)
digits-1
While ((digits>=0) And (*a\l[digits]=0 ))
digits-1
Wend
ProcedureReturn digits+1
EndProcedure
Procedure NN_DigitMult(*a.lng,b,c)
Protected bHigh.i,bLow.i,cHigh.i,cLow.i,t.i,u.i
bHigh=HIGH_HALF(b)
bLow =LOW_HALF(b)
cHigh=HIGH_HALF(c)
cLow =LOW_HALF(c)
*a\l[0]=bLow *cLow
t =bLow *cHigh
u =bHigh*cLow
*a\l[1]=bHigh*cHigh
t=t+u
If groesser(u,t)
*a\l[1]=*a\l[1]+TO_HIGH_HALF(1)
EndIf
u=TO_HIGH_HALF (t)
*a\l[0]=*a\l[0]+u
If groesser(u,*a\l[0])
*a\l[1]+1
EndIf
*a\l[1]+HIGH_HALF(t)
EndProcedure
;Computes a = b + c*d, where c is a digit. Returns carry.
;Lengths: a[digits], b[digits], d[digits].
Procedure NN_AddDigitMult (*a.LNG,*b.LNG,c,*d.LNG,digits)
Protected t.LNG,*t.LNG,carry.i,dc.i,bc.i,ac.i,i.i
*t.LNG=@t
If c=0
ProcedureReturn #False
EndIf
carry = 0
i = digits
dc=0:bc=0:ac=0
While i
i-1
NN_DigitMult(*t, c, *d\l[dc])
dc+1
*a\l[ac]=*b\l[bc]+carry
bc+1
If groesser(carry,*a\l[ac])
carry=#True
Else
carry=#False
EndIf
*a\l[ac] + *t\l[0]
If groesser(*t\l[0],*a\l[ac])
carry+1+*t\l[1]
Else
carry+*t\l[1]
EndIf
ac+1
Wend
ProcedureReturn carry
EndProcedure
;Returns the significant length of a in bits, where a is a digit
Procedure NN_DigitBits(a)
Protected i.i
While a<>0 And i<#NN_DIGIT_BITS
i+1
a=a>>1
Wend
ProcedureReturn i
EndProcedure
;Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
;Lengths: a[digits], b[digits].
;Requires c < NN_DIGIT_BITS.
Procedure NN_LShift(*a.LNG,*b.LNG,c,digits)
Protected t.i,i.i,bc.i,ac.i,dummy.i,carry.i
t=#NN_DIGIT_BITS-c
i=digits
If t<=0
ProcedureReturn #False
EndIf
If c
bc=0:ac=0
While i
i-1
dummy=*b\l[bc]
bc+1
*a\l[ac]=(dummy<<c)|carry
ac+1
carry=dummy>>t&Val(Str((Pow(2,c))-1));????
Wend
Else
NN_Assign (*a.LNG,*b.LNG,digits)
EndIf
ProcedureReturn carry
EndProcedure
;Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
;Lengths: a[digits], b[digits].
;Requires c < NN_DIGIT_BITS. */
Procedure NN_RShift(*a.LNG,*b.LNG,c,digits)
Protected t.i,i.i,ac.i,bc.i,dummy.i,carry.i
t=#NN_DIGIT_BITS-c
i=digits
If t<=0
ProcedureReturn 0
EndIf
If c
bc+i-1:ac+i-1
While i
i-1
dummy=*b\l[bc]
bc-1
*a\l[ac]=((dummy>>c)&Val(Str((Pow(2,t))-1)))|carry
ac-1
carry=dummy<<t;&Val(Str((Pow(2,c))-1));????
Wend
Else
NN_Assign(*a.LNG,*b.LNG,digits)
EndIf
ProcedureReturn carry
EndProcedure
;Sets a = b / c, where a And c are digits.
;Lengths: b[2]
;Assumes b[1] < c And HIGH_HALF (c) > 0. For efficiency, c should be normalized.
Procedure NN_DigitDiv (*a.lng,*b.lng,*c.lng)
Protected t.LNG,*t.LNG,chigh.i,clow.i,ahigh.i,alow,u.i,v.i
*t.lng=@t
cHigh=HIGH_HALF(*c\l[0])
cLow=LOW_HALF(*c\l[0])
*t\l[0]=*b\l[0]
*t\l[1]=*b\l[1]
If cHigh=#MAX_NN_HALF_DIGIT
aHigh=HIGH_HALF(*t\l[1])
Else
aHigh=div(*t\l[1],cHigh + 1)
EndIf
u=aHigh*cLow
v=aHigh*cHigh
*t\l[0]=*t\l[0]-TO_HIGH_HALF(u)
If groesser(*t\l[0],(#MAX_NN_DIGIT-TO_HIGH_HALF(u)))
*t\l[1]-1
EndIf
*t\l[1]=*t\l[1]-(HIGH_HALF(u))
*t\l[1]=*t\l[1]-v
While groesser(*t\l[1],cHigh) Or ((*t\l[1]=cHigh) And groessergleich(*t\l[0],TO_HIGH_HALF(cLow)))
*t\l[0]=*t\l[0]-TO_HIGH_HALF(cLow)
If groesser(*t\l[0],#MAX_NN_DIGIT-TO_HIGH_HALF(cLow))
*t\l[1]-1
EndIf
*t\l[1]=*t\l[1]-cHigh
aHigh+1
Wend
If cHigh=#MAX_NN_HALF_DIGIT
aLow=LOW_HALF(*t\l[1])
Else
aLow=div(TO_HIGH_HALF(*t\l[1])+HIGH_HALF(*t\l[0]),cHigh+1)
EndIf
u=aLow*cLow
v=aLow*cHigh
*t\l[0]=*t\l[0]-u
If groesser(*t\l[0],#MAX_NN_DIGIT-u)
*t\l[1]-1
EndIf
*t\l[0]-TO_HIGH_HALF (v)
If groesser(*t\l[0],(#MAX_NN_DIGIT-TO_HIGH_HALF(v)))
*t\l[1]-1
EndIf
*t\l[1]=*t\l[1]-HIGH_HALF(v)
While groesser(*t\l[1],0) Or ((*t\l[1]=0) And groessergleich(*t\l[0],*c\l[0]))
*t\l[0]-*c\l[0]
If groesser(*t\l[0],#MAX_NN_DIGIT-*c\l[0])
*t\l[1]-1
EndIf
aLow+1
Wend
*a\l[0]=TO_HIGH_HALF (aHigh) + aLow
EndProcedure
;Computes a = b - c*d, where c is a digit. Returns borrow.
;Lengths: a[digits], b[digits], d[digits]. */
Procedure NN_SubDigitMult (*a.LNG, *b.LNG, c, *d.LNG, digits)
Protected t.LNG,*t.LNG,i.i,borrow.i,a.i,b.i,ddc.i,bbc.i,aac.i
*t.LNG=@t
i=digits
If c=0
ProcedureReturn 0
EndIf
ddc=0:bbc=0
While i
i-1
NN_DigitMult(*t,c,*d\l[ddc])
ddc+1
*a\l[aac]=*b\l[bbc]-borrow
borrow=groesser(*a\l[aac], #MAX_NN_DIGIT-borrow)
bbc+1
*a\l[aac]-*t\l[0]
a= (*t\l[1])
b= (groesser(*a\l[aac],(#MAX_NN_DIGIT-*t\l[0])))
borrow = a+b+borrow
aac+1
Wend
ProcedureReturn borrow
EndProcedure
;Returns sign of a - b.
;Lengths: a[digits], b[digits]. */
Procedure NN_Cmp (*a.lng, *b.lng, digits)
Protected i.i
For i=digits-1 To 0 Step-1
If groesser(*a\l[i],*b\l[i])
ProcedureReturn 1
EndIf
If groesser(*b\l[i],*a\l[i])
ProcedureReturn -1
EndIf
Next i
ProcedureReturn 0
EndProcedure
;Computes a = b - c.
;Lengths: a[digits], b[digits], c[digits]
;Returns borrow.
Procedure NN_Sub(*a.LNG,*b.LNG,*c.LNG,digits)
Protected ac.i,bc.i,cc.i,ai.i,borrow.i
ac=0:bc=0:cc=0
While digits>0
digits-1
ai=*b\l[bc]-borrow
bc+1
If groesser(ai,(#MAX_NN_DIGIT-borrow))
ai=#MAX_NN_DIGIT-*c\l[cc]
cc+1
Else
ai=ai-*c\l[cc]
If groesser(ai,(#MAX_NN_DIGIT-*c\l[cc]))
borrow=#True
Else
borrow=#False
EndIf
cc+1
EndIf
*a\l[ac]=ai
ac+1
Wend
ProcedureReturn borrow
EndProcedure
;Computes a = c div d And b = c mod d.
;Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].
;Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,dDigits < MAX_NN_DIGITS.
Procedure NN_Div (*a.lng,*b.lng,*c.lng,cDigits,*d.lng,dDigits)
Protected cc1.LNG, DD1.LNG,*cc.lng,*dd.lng,dddigits.i,shift.i,t.i,i.i,km.i,ai.i,k.i,tz.i,a.i
*cc.LNG=@cc1
*dd.LNG=@dd1
ddDigits=NN_Digits(*d, dDigits)
If ddDigits=0
ProcedureReturn
EndIf
;Normalize operands
shift=#NN_DIGIT_BITS-NN_DigitBits(*d\l[ddDigits-1])
NN_AssignZero(*cc, ddDigits)
*cc\l[cDigits]=NN_LShift(*cc,*c,shift,cDigits)
NN_LShift (*dd,*d,shift,ddDigits)
t=*dd\l[ddDigits-1]
NN_AssignZero(*a,cDigits)
For i=cDigits-ddDigits To 0 Step-1
;Underestimate quotient digit And subtract.
km = #MAX_NN_DIGIT
If t = km
ai=*cc\l[i+ddDigits]
Else
k=t+1
NN_DigitDiv (@ai,@*cc\l[i+ddDigits-1],@k)
EndIf
a=NN_SubDigitMult(@*cc\l[i],@*cc\l[i],ai,*dd, ddDigits)
*cc\l[i+ddDigits] -a
tz=0
While (groesser(*cc\l[i+ddDigits],0)) Or (NN_Cmp (@*cc\l[i],*dd, ddDigits)>=0)
ai+1
tz+1
*cc\l[i+ddDigits]-NN_Sub(@*cc\l[i],@*cc\l[i],*dd,ddDigits)
Wend
*a\l[i]=ai
Next i
;Restore result.
NN_AssignZero(*b, dDigits)
NN_RShift(*b,*cc, shift,ddDigits)
EndProcedure
;Computes a = b * c.
;Lengths: a[2*digits], b[digits], c[digits].
;Assumes digits < MAX_NN_DIGITS.
Procedure NN_Mult(*a.LNG,*b.LNG,*c.LNG,digits)
Protected t.LNG,*t.lng,bdigits.i,cdigits.i,dummy.i,i.i
*t.LNG=@t
NN_AssignZero (*t,2*digits)
bDigits=NN_Digits (*b,digits)
cDigits=NN_Digits (*c,digits)
For i=0 To bDigits-1
dummy=NN_AddDigitMult(@*t\l[i],@*t\l[i],*b\l[i],*c,cDigits)
*t\l[i+cDigits]+dummy
Next i
NN_Assign (*a,*t,2*digits)
EndProcedure
;Computes a = b mod c.
;Lengths: a[cDigits], b[bDigits], c[cDigits].
;Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.
Procedure NN_Mod (*a.LNG,*b.LNG,bDigits,*c.LNG,cDigits)
Protected t.LNG,*t.lng
*t.LNG=@t
NN_Div(*t, *a, *b,bDigits,*c,cDigits)
EndProcedure
;Computes a = b * c mod d.
;Lengths: a[digits], b[digits], c[digits], d[digits].
;Assumes d > 0, digits < MAX_NN_DIGITS.
Procedure NN_ModMult(*a.LNG,*b.LNG,*c.LNG,*d.LNG,digits)
Protected t.LNG,*t.lng
t.LNG
*t.LNG=@t
NN_Mult(*t,*b,*c,digits)
NN_Mod (*a,*t,2*digits,*d,digits)
EndProcedure
Procedure NN_ModExp(*a1,*b1,*c1,cDigits,*d1,dDigits)
Protected a.LNG,*a.lng,b.LNG,*b.lng,c.LNG,*c.lng,d.LNG,*d.lng,t.LNG,*t.lng
Protected bPower.LNG_3,*bPower.LNG_3
Protected i.i,j.i,ci.i,cibits.i,s.i
*a.lng=@a
*b.lng=@b
*c.lng=@c
*d.lng=@d
CopyMemory(*a1,*a,4*dDigits)
CopyMemory(*b1,*b,4*dDigits)
CopyMemory(*c1,*c,4*cDigits)
CopyMemory(*d1,*d,4*dDigits)
*bPower.LNG_3 = @bpower
*t.LNG=@t
;Store b, b^2 mod d, And b^3 mod d.
NN_Assign (@*bPower\lng[0]\l,*b,dDigits)
NN_ModMult(@*bPower\lng[1]\l,@*bPower\lng[0]\l,*b,*d,dDigits)
NN_ModMult(@*bPower\lng[2]\l,@*bPower\lng[1]\l,*b,*d,dDigits)
NN_ASSIGN_DIGIT (*t,1,dDigits)
cDigits=NN_Digits (*c,cDigits)
For i=cDigits-1 To 0 Step -1
ci=c\l[i]
ciBits=#NN_DIGIT_BITS
;Scan past leading zero bits of most significant digit.
If i=cDigits-1
While DIGIT_2MSB (ci)=0
ci<<2
ciBits-2
Wend
EndIf
For j = 0 To ciBits-1 Step 2
;Compute t = t^4 * b^s mod d, where s = two MSB's of ci.
NN_ModMult(*t,*t,*t,*d,dDigits)
NN_ModMult(*t,*t,*t,*d,dDigits)
s=DIGIT_2MSB(ci)
If s <>0
NN_ModMult(*t,*t,@*bPower\lng[s-1]\l,*d,dDigits)
EndIf
ci<<2
Next j
Next i
NN_Assign(*a,*t,dDigits)
;Zeroize potentially sensitive information.
CopyMemory(*a,*a1,4*dDigits)
CopyMemory(*b,*b1,4*dDigits)
EndProcedure
Procedure NN_DecodeLE(*a.LNG,*b.LNG,len)
Protected i.i
For i=0 To len-1
PokeB(*a+len-i-1,PeekB(*b+i))
Next i
EndProcedure
; *********************** T E S T ****************************
Procedure.s speicherout_hex(*mem,l,q$)
Protected i.i
For i=0 To l-1
q$+RSet(Hex(PeekA(*mem+i)),2,"0")+" "
Next i
ProcedureReturn q$
EndProcedure
DataSection
d: ;Schlüssel d
Data.b $77,$cd,$df,$07,$67,$36,$a3,$c5
Data.b $34,$0a,$bd,$03,$01,$79,$9b,$22
Data.b $2e,$e4,$f4,$70,$df,$c1,$01,$08
Data.b $79,$b6,$ba,$1e,$fd,$52,$e5,$0c
Data.b $af,$a0,$87,$ed,$1f,$63,$6e,$54
Data.b $b4,$4b,$eb,$5c,$1f,$a1,$71,$0d
Data.b $c7,$e8,$65,$09,$da,$a4,$a5,$fc
Data.b $d5,$f9,$06,$e3,$6e,$a4,$8c,$3b
e: ;Schlüssel e
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$00
Data.b $00,$00,$00,$00,$00,$00,$00,$03
n: ;Schlüssel n
Data.b $b3,$b4,$ce,$8b,$1a,$d1,$f5,$a7
Data.b $ce,$10,$1b,$84,$82,$36,$68,$b3
Data.b $46,$57,$6e,$a9,$4f,$a1,$81,$8c
Data.b $b6,$92,$17,$2e,$7b,$fc,$57,$94
Data.b $b6,$61,$13,$8a,$6f,$2a,$a6,$26
Data.b $65,$47,$c5,$d8,$de,$68,$82,$eb
Data.b $49,$38,$51,$d7,$eb,$38,$77,$7f
Data.b $16,$b1,$bb,$b9,$e4,$fc,$6d,$3b
EndDataSection
Define a.i,d_lsb.i,e_lsb.i,n_lsb.i,c.i,m.i,m1.i
d_lsb = AllocateMemory(64)
e_lsb = AllocateMemory(64)
n_lsb = AllocateMemory(64)
c = AllocateMemory(64)
m = AllocateMemory(64)
m1 = AllocateMemory(64)
;MSB <-> LSB
NN_DecodeLE (d_lsb,?d,64)
NN_DecodeLE (e_lsb,?e,64)
NN_DecodeLE (n_lsb,?n,64)
NN_AssignZero(m,64) ; speicher nullen
PokeS(m,"Das ist ein Test mit 512bit RSA zu verschlüsseln (max 64 Byte)") ; speicher füllen
Debug speicherout_hex(m,64,"plain: in HEX: ")
;verschlüsseln
NN_ModExp (c,m,e_lsb,16,n_lsb,16)
Debug speicherout_hex(c,64,"verschlüsselt: ")
;entschlüsseln
NN_ModExp (m1,c,d_lsb,16,n_lsb,16)
Debug speicherout_hex(m1,64,"entschlüsselt: ")
Debug PeekS(m1)