Rabbit Cipher - Module

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Rabbit Cipher - Module

Post by Saki »

Hi StarBootics
I did not know this statement.
But the speed is not important for many applications.
Especially as the computers also are getting faster and faster.

But it's nice to see that you work on these things and enjoy it again and again.

Best Regards Saki
地球上の平和
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

Saki wrote:But it's nice to see that you work on these things and enjoy it again and again.
It's because I believe more in PureBasic than Fred him self !

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

StarBootics wrote:@Wilbert : You are saying that the original C code was wrong as well ?
No.
In the C source X, C and Carry from the Rabbit structure are unsigned 32 bit integers.
In your code this isn't the case. As a result of this the carry detection in your code is wrong.

Code: Select all

Old.l = 2147483647
New.l = Old + 10
Debug Old
Debug New
In this example, the new value is smaller as the old one so your code says there's a carry.
For an unsigned 32 bit value there is no carry. The new value would simply be 2147483657.

Using a quad also doesn't help

Code: Select all

Old.q = 4294967295
New.q = Old + 10
Debug Old
Debug New
In this case if Old and New would be unsigned 32 bit integer values there would be a carry (New would have a value of 9) but using a quad the carry isn't detected.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

I see. But a simple example can be made with PureBasic :

Code: Select all

Old.l = 2147483647
New.l = Old + 10

Debug Old
Debug New

Old2.u = 65535
New2.u = Old2 + 10

Debug Old2
Debug New2
By the way it's not the only problem in my code. The g function also has some issues as well, in some cases we are exceeding the Quad positive limit and the "l" temporary variable become negative. :?

It's not going to be an easy fix ?

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

StarBootics wrote:It's not going to be an easy fix ?
You need to work around the signed/unsigned int problems.
It's possible but mistakes are easy made and compared to a native unsigned int type, the workarounds have a negative effect on the performance.
I don't know what the algorithm usually is used for. If it's only small amounts of data it has to process the negative performance impact probably isn't a big problem.
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

Sorry StarBootics, I see now your carry detection approach with the quads should be fine. :oops:
I didn't look properly at what U32V does.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

wilbert wrote:Sorry StarBootics, I see now your carry detection approach with the quads should be fine. :oops:
I didn't look properly at what U32V does.
I was just about to return to you about that but ...

Anyway are the values tested be the one that we are expecting ? I'm not sure about that but just to be safe I will use this procedure :

Code: Select all

Procedure.q Addition(VarA.q, VarB.q)

  Result.q = VarA + VarB
  
  If Result > 4294967295
    Result = Result - 4294967296
  EndIf
  
  ProcedureReturn Result
EndProcedure
VarA will be a previous output of the procedure so should be OK. VarB will be one of these constants plus 0 or 1 :

Code: Select all

a0 = $4D34D34D 
a1 = $D34D34D3
a2 = $34D34D34
a3 = $4D34D34D
a4 = $D34D34D3 
a5 = $34D34D34
a6 = $4D34D34D 
a7 = $D34D34D3
So VarB will always be OK.

What I'm struggling with right now is how to Square a value and get the unsigned integer value stored inside a Quad. So I have a cup of coffee and I will try to solve this issue. Wish me luck.

Best regards
StarBootics
Last edited by StarBootics on Fri Nov 06, 2020 11:15 am, edited 1 time in total.
The Stone Age did not end due to a shortage of stones !
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Rabbit Cipher - Module

Post by Demivec »

Another factor that you will have to address for lack of unsigned integers is the bit shift functions. Right bit-shift operations with '>>' will extend the sign bit to the right instead of filling the bits with zero. So your ROL32 function won't function as is to produce the same output as would be produced with unsigned integers. The same is true for anywhere you use the '>>' operator.
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

Hello everyone,

@Demivec : Thanks for your input, I will revise those macros later.

I have a partial solution for Squaring values unfortunately it work fine up to 3037000499. For any value bigger than that I don't have the solution yet and I have seen values bigger than that.
This is the not optimized code for the moment.

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : Simulation of Squaring Unsigned long
; File Name : Simulation of Squaring Unsigned long.pb
; File version: 0.0.0
; Programming : Under development
; Programmed by : StarBootics
; Date : November 5th,2020
; Last Update : November 5th,2020
; PureBasic code : V5.73 beta 2
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure.q Addition(VarA.q, VarB.q)
  
  Result.q = VarA + VarB
  
  If Result > 4294967295
    Result = Result - 4294967296
  EndIf
  
  If Result < 0
    Result = 4294967296 + Result
  EndIf
  
  ProcedureReturn Result
EndProcedure

Procedure.q Squaring(Value.q)
  
  Square.q = Value * Value
  Output.q = 0
  
  If Square < 0
    
    ; This portion of the code just don't work at all
    
    Debug "Square Négatif (" + Str(Value) + ")"
    
    Output = Addition(Output, 2147483647)
    Output = Addition(Output, -1533320537)
    
    Amount2.q = Square * -1
    Debug Amount2

    HowManyLoopOfWaste = Amount2 / 4294967295
    Debug -HowManyLoopOfWaste
    Amount2 = Amount2 - HowManyLoopOfWaste * 4294967295
    Debug Amount2
    Output = Addition(Output, Amount2)
    Output = Addition(Output, -HowManyLoopOfWaste)
    
    ;
    
  ElseIf Square > 0
    
    ; This portion of the code work just fine
    
    Debug "Square Positif (" + Str(Value) + ")"
    HowManyLoopOfWaste = Square / 4294967295
    Amount.q = Square - HowManyLoopOfWaste * 4294967295
    Output = Addition(Output, Amount)
    Output = Addition(Output, -HowManyLoopOfWaste)
    
  EndIf
  
  ProcedureReturn Output
EndProcedure

Debug Squaring(3037000499) ; Squaring this value still fit inside of the
                           ; positive portion of a Quad. The simulated
                           ; unsigned value is Correct

Debug Squaring(3037000500) ; Squaring this value don't fit inside the
                           ; positive portion of a Quad. The simulated
                           ; unsigned value is not Correct

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
@Fred : if you ever read this topic please consider adding unsigned long variables back into PureBasic. Even if certain operations like comparing signed and unsigned values are not possible I can live with that. I know I'm pushing the PureBasic envelope by doing this just to see if it's possible but with unsigned long this project will be completed already.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

@StarBootics, you are making things overly complicated.
Try if this works

Code: Select all

Procedure.q RABBIT_GFunc(x.q)
  x*x
  ProcedureReturn U32V(x ! (x >> 32))
EndProcedure
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

@Wilbert : Hey don't look at me for the over complicated G function it was the direct translation from the original C code. That being said I have compared your take on the G function and compare the result with the C/C++ version of the function and it work, so thanks for that.

But to calculate the g values I still need to use the Addition() function like that :

Code: Select all

    ; Calculate the g-values
    
    For Index = 0 To 7
      Temp\g[Index] = RABBIT_GFunc(Addition(*Rabbit\X[Index], *Rabbit\C[Index]))
    Next
So the solution in the end will not be so taxing in terms of performance. Not as it would be if we have native unsigned long variables, but where will the fun be then ?

Now I need to verify the ROTL32() and SWAP32() macros to make sure we have the expected result as Demivec pointed out.

See you later, I have an appointment in less than hour and I have to leave.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

Hello everyone,

Just to let you know that I have updated the first post with the Version 3.0.0 of the module with better examples. I have finally manage to make it to work according to RFC 4503 Rabbit Cipher of May 2006 Appendix B: Debugging Vectors.

Please be advise the key provided in that document contain a faulty value. This is the one presented in the document :
key = [91 28 13 29 2E ED 36 FE 3B FC 62 F1 DC 51 C3 AC]
This is the correct one :
key = [91 28 13 29 2E 3D 36 FE 3B FC 62 F1 DC 51 C3 AC]
I have spent 4 hours of trying, checking and testing before to find the error.

@Demivec : The Rotate Left and Right bit-shift work as expected as is. Nothing to do to make them to work. This is due to the fact that we are working with the first 32-bit of a 64-bit variables

I now have few related libraries to update so I will take a little break before posting a library to Read / Write on file similar to Read Write AES - OOP one.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

In the reference implementation U32TO32_LITTLE does nothing on little endian machines like x86 / x64.
It is only on big endian machines that this function swaps bytes.

You are using the test vectors in a wrong way in your code.
What you are doing is encrypting and decrypting the test vector and see if the result still matches the original one. That's not what the test vectors are for.
This way you can change any value from out2 in the data section and it will always show success.
The test vectors contain the bytes that are used to xor against the unencrypted input for a given key.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Rabbit Cipher - Module

Post by StarBootics »

wilbert wrote:In the reference implementation U32TO32_LITTLE does nothing on little endian machines like x86 / x64.
It is only on big endian machines that this function swaps bytes.

You are using the test vectors in a wrong way in your code.
What you are doing is encrypting and decrypting the test vector and see if the result still matches the original one. That's not what the test vectors are for.
This way you can change any value from out2 in the data section and it will always show success.
The test vectors contain the bytes that are used to xor against the unencrypted input for a given key.
It's not the only issue we have, since I'm using PeekL() and PokeL() I'm introducing sign bit into the mix of bits and this is not good at all once again. I need to program special PeekU32() and PokeU32(). I Can't sleep this night so I will work on this issue.

The main problem I have about testing is the fact that in many example they don't tell something like this :

With this Key, this Init vector and this input you should have this output they don't provide that information.

I will address all of that this night. See you tomorrow.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Rabbit Cipher - Module

Post by wilbert »

I'll try to create a working asm version as well.
Some prefer the speed of asm, others the readability of normal basic code.
But it might help to compare the results of the two against each other.
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply