RSA-Verschlüsselungs-Algorythmus in PB

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von Sunny »

Ja, aslo...
ich wollte mal Fragen, wie ich einen RSA-Verschlüsselungs-Algorythmus in PB realisiere. Ich hab mich zwar schon viel darüber informiert (Wikipedia / Youtube) aber irgendwie fehlt mir zum Verständniss dazu das mathematische Hintergrundwissen.
andi256
Beiträge: 100
Registriert: 06.11.2004 11:23
Computerausstattung: PB 5.30 (x64) Win7
Wohnort: Österreich

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von andi256 »

Naja der RSA Algo ist im Endeffekt ja ziemlich simpel :

Verschlüsseln c = m^e mod n

Entschlüsseln m = c^d mod n

m ..Message
c .. chipper (verschlüsselte Text)

d .. ist der geheime Exponent
e .. ist der private Exponent
n .. der modulus
wie man die drei Schüsseln erstellt ist ein anderes Kapitel … (wiki etc)

also mathematisch braucht man dazu nur diese Rechnung und man kann ver/entschlüsseln
a = b^c mod n

Code: Alles auswählen

Bsp.  -> Schlüssel erstellen (p=11 / q=13)  (http://de.wikipedia.org/wiki/RSA-Kryptosystem)

m = 7

n = 11*13 =  143
e = 23
d = 47

verschlüsseln
c = 7^23 mod 143 = 2


entschlüsseln
m = 2^47 mod 143 = 7
Soweit ja nicht aufregend sofern man mit der „Modulo Rechnung“ und „Exponentialrechnung“ vertraut ist…

in der Praxis kämpft man hier jedoch mit 2 Problemen

1) Da zb. ein 1024bit RSA mit riesigen Zahlen arbeitet ( 2^1024 = dezimal Zahl mit unzähligen Nullen) und diese auch noch Exponential gerechnet werden muss, braucht man einen speziellen Algorithmus um das zu bewerkstelligen.
(das Ergebnis von m^e könnte man bei einer Praktischen Anwendung nicht auf allen Computern der Welt speichern da die Zahl grösser wäre als alle Atome im Universum!)

(der Algorithmus bewerkstelligt das indem er den Exponenten zerlegt und dazwischen immer wieder die Modulo Rechnung ausführt)

2) Man muß sich überlegen wie man mit den großen Zahlen arbeitet … der PC / PB kennt ja nur Zahlen wie zb „long“ … 4Byte … auch mit den größeren Typen wie zb.Quad kommt man beim RSA nicht weit da man mit Zahlen von zb. 64Byte rechnen muß ..
Das bedeuten man muss sich die Rechnungs arten mit Multiplizieren etc. selber programmiern.

Weiters muß man überlegen wie man die Zahlen / Ergebnisse speichert … Strings sicnd hier im endeffekt nur zur ein und ausgabe nützlich zum Rechnen muß man hier anders ansetzten…

a) Zahlen werden nur in Hexadzimal gerechnet (-> Umrechnung von dezimal in Hexadzimal sollte kein Problem sein)
(In meinen Bsp. wird in 4Byte Blöcken gerechnet)
b) Diese werden in Speicherblöcken abgelegt …. Hier gibt 2 Möglichkeiten: LSB <-> MSB
(wird in meinen Beispiel wird LSB benutzt da das gewisse Vorteile mit sich bringt)

Beispiel
Der Wert von 125000 EURO wird in HEX umgerechnet 00 01 E8 48 und wird in einem Speicherblock 48 E8 01 00 abgelegt …


Der Code selber wurde von mir im Jahr 2005 von sourceforge.net ins PB übersetzt ….
http://forums.purebasic.com/german/view ... d706219e1c

Es gilt:
Copyright (C) RSA Laboratories, a division of RSA Data Security,
Inc., created 1991. All rights reserved.
Hat damals bei meinen Programmen zum RSA rechnen gereicht …. Jedoch keine gewähr auf Richtigkeit 

Code: Alles auswählen

;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)
 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)
 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)
 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)
 t.LNG
 *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)  
 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)
 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)
 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)
 t.LNG
 *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)
  t.LNG
  *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)
 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)
 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)
 cc1.LNG
 DD1.LNG
 *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.l = #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)
 t.LNG
 *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)
 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)
 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)
 a.LNG
 b.LNG
 c.LNG
 d.LNG
 
 *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.LNG_3 = @bpower
 
 t.LNG
 *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


; *********************** T E S T ****************************

Procedure UpeekB(*mem)
 ProcedureReturn Val(StrU(PeekB(*mem),#PB_Byte))
EndProcedure

Procedure.s speicherout_hex(*mem,l,q$)
 For i=0 To l-1
  q$=q$+RSet(Hex(UPeekB(*mem+i)),2,"0")+" "
 Next i
ProcedureReturn q$
EndProcedure

; Beispiel hier sind keine gültigen RSA Schlüssel !
;Zahl1 = "12345678901234567890"
;Zahl2 = "123456789012345"
;Zahl3 = "987654321098765"

;Zahl1inhex = "AB 54 A9 8C EB 1F 0A D2"
;Zahl2inhex = "70 48 86 0D DF 79"
;Zahl3inhex = "03 82 44 30 F8 50 0D"

; Alle Funktionen rechen in little endian
; daher umwandeln in "little endian" LSB (LeastSignificantByte)
DataSection
Zahl1inhexLSB:
Data.b $D2,$0A,$1F,$EB,$8C,$A9,$54,$AB
; auffüllen mit Nullen (immer in 4er Blöcken (Longs) hier 8Byte entspricht 2xlongs
Zahl2inhexLSB:
Data.b $79,$DF,$0D,$86,$48,$70,$00,$00
Zahl3inhexLSB:
Data.b $0D,$50,$F8,$30,$44,$82,$03,$00
EndDataSection

*a=AllocateMemory(16)
;           erg =     a      ^      b     mod      c
; die beiden "2"er hier gebe die länge der Zahlen an "2" x 4BYTE(long)
NN_ModExp (*a,?Zahl1inhexLSB,?Zahl2inhexLSB,2,?Zahl3inhexLSB,2)

Debug speicherout_hex(*a,8,"")

; -> ergebnis 12 BB 29 98 C9 86 02 00

; LSB-MSB
;Ergebniss in hex "286C99829BB12"
;Ergebniss in dez "711150352841490"
Andi256
andi256
Beiträge: 100
Registriert: 06.11.2004 11:23
Computerausstattung: PB 5.30 (x64) Win7
Wohnort: Österreich

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von andi256 »

anbei noch ein Test mit 512 Bit RSA

Code: Alles auswählen

; *********************** T E S T ****************************

Procedure UpeekB(*mem)
 ProcedureReturn Val(StrU(PeekB(*mem),#PB_Byte))
EndProcedure

Procedure.s speicherout_hex(*mem,l,q$)
 For i=0 To l-1
  q$=q$+RSet(Hex(UPeekB(*mem+i)),2,"0")+" "
 Next i
ProcedureReturn q$
EndProcedure


;schlüssel erstellt : http://www.pepta.net/

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

*d_lsb = AllocateMemory(64)
*e_lsb = AllocateMemory(64)
*n_lsb = AllocateMemory(64)

*c     = AllocateMemory(64)
*m     = 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 (*m,*c,*d_lsb,16,*n_lsb,16)

Debug speicherout_hex(*m,64,"entschlüsselt: ")

Debug PeekS(*m)
Zuletzt geändert von andi256 am 08.05.2013 16:39, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von NicTheQuick »

@andi256:
Coole Sache! :allright:
Es scheint schon ein etwas älterer Code zu sein. Deswegen als Tipp für dich:

Code: Alles auswählen

Procedure UpeekB(*mem)
 ProcedureReturn Val(StrU(PeekB(*mem),#PB_Byte))
EndProcedure
Dieses hässliche Konstrukt kannst du komplett entfernen und statt 'UpeekB()' nimmst du ab sofort einfach nur 'PeekA()', denn der Datentyp 'Ascii' mit der Endung '.a' stellt sozusagen ein 'unsigned char' wie man es aus C kennt dar.
Keya
Beiträge: 4
Registriert: 18.06.2015 19:40

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von Keya »

Hello, sorry I only speak English, but andi256 your RSA code is excellent, thankyou!!! :)

However it crashes under Linux32 (i havent tried 64) with memory corruption error ... it seems the problem is actually the "speicherout_hex()" procedure! but despite my attempts and various unicode/non-unicode Peeks/compiler options etc I cant work out exactly why. Its just a display issue though, nothing major!
andi256
Beiträge: 100
Registriert: 06.11.2004 11:23
Computerausstattung: PB 5.30 (x64) Win7
Wohnort: Österreich

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von andi256 »

Hello,

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)

please disabled unicode
(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)
Keya
Beiträge: 4
Registriert: 18.06.2015 19:40

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von Keya »

Well, the speicherout_hex seems fine now in that version on Linux32 :)

But now it's crashing (only Linux32, not Windows) on line 80 according to PB IDE compile output window (this is when run from within PB IDE, with Debugger Enabled):
[ERROR] RSA.pb (Line: 80)
[ERROR] Program aborted. (by external library)
This is the "EndProcedure" line (it gets highlighted red) in NN_AssignZero()

If I comment out the single call to NN_AssignZero it works fine! :)

The NN_AssignZero call doesn't actually seem needed in this case anyway?... because it's basically right after the AllocateMemory() call which doesnt use the #PB_Memory_NoClear flag (so it would be attempting to zero the buffer twice)

Anyway so I compiled it as a console linux app (Debugger=Off, Unicode=Off) and simply changed Debug() to PrintN() ... the code it's failing on looks like this:

Code: Alles auswählen

PrintN("Calling NN_AssignZero...")
NN_AssignZero(m,64)
PrintN("After NN_AssignZero")
PokeS(m,"Das ist ein Test mit 512bit RSA zu verschlusseln (max 64 Byte)")
PrintN("After PokeS")
PrintN (speicherout_hex(m,64,"plain: IN HEX: "))
The resulting output...

Code: Alles auswählen

administrator@mint32vm /media/sf_VMSharedFolder/PB/RSA $ ./RSA
Calling NN_AssignZero...
After NN_AssignZero
RSAnew.elf: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size ==0) ||((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
Aborted
administrator@mint32vm /media/sf_VMSharedFolder/PB/RSA $

By the look of that output it would first appear that 'PokeS' is the problem, not NN_AssignZero ... _BUT_ then I simply commented-out the call to NN_AssignZero, and the compiled elf ran fine! :)

So there seems to be a problem with NN_AssignZero()! ... but speicherout_hex() is working fine now :)

I don't know what's wrong with it though, it looks fine to me...

Code: Alles auswählen

;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

HOWEVER! ... all of the other calls to NN_AssignZero DO work fine! ... it's ONLY the one at program startup (nearly immediately after AllocateMemory) that it's failing on.

So I chopped it down to just the barest ...

Code: Alles auswählen

EnableExplicit

#MAX_NN_DIGITS        =128

Structure LNG
 l.l[#MAX_NN_DIGITS]    ; ;Maximum digits  #MAX_NN_DIGIT         
EndStructure


;Assigns a = 0.
;Lengths: a[digits].
Procedure NN_AssignZero(*a.LNG,digits)
 PrintN("INSIDE NN_ASSIGNZERO")
 Protected i.i
 For i=0 To digits-1
  *a\l[i]=0
 Next i
EndProcedure

Define m.i

OpenConsole()

m     = AllocateMemory(64)

PrintN("Calling NN_AssignZero...")
NN_AssignZero(m,64)  ; speicher nullen
PrintN("After NN_AssignZero")
PokeS(m,"Das ist ein Test mit 512bit RSA zu verschlüsseln (max 64 Byte)")  ; speicher füllen
PrintN("After PokeS")
But that works fine... no crash! :roll:
andi256
Beiträge: 100
Registriert: 06.11.2004 11:23
Computerausstattung: PB 5.30 (x64) Win7
Wohnort: Österreich

Re: RSA-Verschlüsselungs-Algorythmus in PB

Beitrag von andi256 »

mmm.....

it seems to be tricky

something goes wrong with memory ... but i dont see the error

can you test with the Fillmemory funktion ?

Code: Alles auswählen

Procedure NN_AssignZero(*a.LNG,digits)
  FillMemory(*a, digits , 0 , #PB_Byte)
EndProcedure
anyway for this sample i also dont need the "empty memory" it works also without it.
(but it has to be tested at more RSA examples)

Code: Alles auswählen

Procedure NN_AssignZero(*a.LNG,digits)
; do nothing
EndProcedure
i have transate this code a long time ago ... and so many things can be make better (new PB funktions / PeekA / long<>integer ... etc....)

(sorry about my bad english :-)
andi256
Antworten