• 0

Nexys 100T FPGA Implementation of RC4 Stream Cipher


Question

Posted (edited)

Hello,  (FPGA board is Nexys A7 100T) 

So my end goal is to implement RC4 stream cipher and implement it onto FPGA. I was trying to configure a switch that will utilize the 7-segment 8- digital display and display my original plain text.  And another switch that will display the encrypted text.  I have attached the sources and test benches below that works. And have screen captured the simulation to show the results. 

Thanks for spending the time, I'll be high alert for response and try to respond on follow up questions. Can someone help me with this? 

 

Capture.PNG

Edited by Katherine
Link to post
Share on other sites

4 answers to this question

Recommended Posts

  • 0
Posted (edited)

Hi!

RC4 was designed so that it doesn't map well to dedicated hardware, but uses only a small amount of compute power so it can be implemented on all but the tiniest microcontrollers, so implementing it in an FPGA is a great learning experience of what software problems are hard in hardware, and why.

I looked into implementing RC4 a long while ago, and decided that a high performance implementation is pretty much impossible (where high performance is greater than one byte encoded/decoded per cycle).

I've had a look at your code, and it looks like you are writing only for simulation. For example:

    -- Initialize and return an integer array 0 - 255
    function initialS256 return t_Integer_Array is
        variable S: t_Integer_Array(0 to 255);
        begin
         
            for i in 0 to 255 loop
                S(i) := i;
            end loop;
            return S;
    end initialS256;

This won't turn into useful hardware if you try to implement it in an FPGA.

What you want to do is restructure it around some sort of block diagram style system, with a big focus on how you intend to store the array that holds the cipher state - is it all in a block RAM, held in distributed RAM, or just in 65366 flip-flops? Each has a different set of restrictions that limit how you can describe the hardware.

What are you doing the project for? Is it for a course or self-directed learning? 

As for the 7-seg, you should be able to find other posts covering that here and/or in the FPGA reference manual, or the Digilent GithHub repo.

Edited by hamster
Link to post
Share on other sites
  • 0
Posted (edited)

Oh, here is a paper that might provide some insight... have a search for "Efficient FPGA Implementation of the RC4 Stream Cipher using Block RAM and Pipelining filetype:pdf"

(The URL was too long to post here).

 

Edited by hamster
Link to post
Share on other sites
  • 0
Posted (edited)

Ok - here's how to drive the seven segments, from 1000 feet up.

You need to have the constraints for the segments and the anodes for the display. See the board's reference manual and master UCF file for them.

##7 segment display
#set_property -dict { PACKAGE_PIN T10   IOSTANDARD LVCMOS33 } [get_ports { CA }]; #IO_L24N_T3_A00_D16_14 Sch=ca
#set_property -dict { PACKAGE_PIN R10   IOSTANDARD LVCMOS33 } [get_ports { CB }]; #IO_25_14 Sch=cb
#set_property -dict { PACKAGE_PIN K16   IOSTANDARD LVCMOS33 } [get_ports { CC }]; #IO_25_15 Sch=cc
#set_property -dict { PACKAGE_PIN K13   IOSTANDARD LVCMOS33 } [get_ports { CD }]; #IO_L17P_T2_A26_15 Sch=cd
#set_property -dict { PACKAGE_PIN P15   IOSTANDARD LVCMOS33 } [get_ports { CE }]; #IO_L13P_T2_MRCC_14 Sch=ce
#set_property -dict { PACKAGE_PIN T11   IOSTANDARD LVCMOS33 } [get_ports { CF }]; #IO_L19P_T3_A10_D26_14 Sch=cf
#set_property -dict { PACKAGE_PIN L18   IOSTANDARD LVCMOS33 } [get_ports { CG }]; #IO_L4P_T0_D04_14 Sch=cg
#set_property -dict { PACKAGE_PIN H15   IOSTANDARD LVCMOS33 } [get_ports { DP }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
#set_property -dict { PACKAGE_PIN J17   IOSTANDARD LVCMOS33 } [get_ports { AN[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
#set_property -dict { PACKAGE_PIN J18   IOSTANDARD LVCMOS33 } [get_ports { AN[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
#set_property -dict { PACKAGE_PIN T9    IOSTANDARD LVCMOS33 } [get_ports { AN[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
#set_property -dict { PACKAGE_PIN J14   IOSTANDARD LVCMOS33 } [get_ports { AN[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
#set_property -dict { PACKAGE_PIN P14   IOSTANDARD LVCMOS33 } [get_ports { AN[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
#set_property -dict { PACKAGE_PIN T14   IOSTANDARD LVCMOS33 } [get_ports { AN[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
#set_property -dict { PACKAGE_PIN K2    IOSTANDARD LVCMOS33 } [get_ports { AN[6] }]; #IO_L23P_T3_35 Sch=an[6]
#set_property -dict { PACKAGE_PIN U13   IOSTANDARD LVCMOS33 } [get_ports { AN[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]

I suggest you update them so the first 8 are called "segments[0]" through "segments[7]" and the last 8 are "anodes[0]" through "anodes[7]";

You will also need constraints for the other signals you are using - e.g. the clock signal.

You will then need to add the output to the top level design:

...
   segments : out std_logic_vector(7 downto 0);
   anodes  :out  std_logic_vector(7 downto 0);
...

 

In your top level design. you can select which digit to light by setting one of the anodes to low, and also setting the patterns you want on the segments. For example:

  anodes <= "11111110";
  segments <="0101010";

should light segment B, D, F and the Decimal port on digit 0 of the display. See section 9.1 of the reference manual to see which segment is where on the display.

With that going you will then want to add a new sub-module to your design, that takes the 8 digits you want to display, and converts them to a pattern of segments and anodes, at a slow enough speed that they don't flicker (e.g. show each digit for 1/400th of a second, then move onto the next.

The interface to this component will be something like:

 

entity  seven_seg_display is 
   port (
      clk  : in std_logic;

      digit0 : in std_logic_vector(3 downto 0);
      digit1 : in std_logic_vector(3 downto 0);
      digit2 : in std_logic_vector(3 downto 0);
      digit3 : in std_logic_vector(3 downto 0);
      digit4 : in std_logic_vector(3 downto 0);
      digit5 : in std_logic_vector(3 downto 0);
      digit6 : in std_logic_vector(3 downto 0);
      digit7 : in std_logic_vector(3 downto 0);

      segments : out std_logic_vector(7 downto 0);
      anodes   : out std_logic_vector(7 downto 0)
);
end component;

Once you you have that module connected, and with the body of it written (it is a counter and a few case statements) you should then do a bit of testing (eg. connect the switches to the digits)  and should be ready to do display your data. This testing step is vital, to ensure that your LED patterns are correct, and you have got left and right correct for the anodes.

Another test might be to create a 32-bit long counter, and then connect the digits to bit slices within that counter.

Edited by hamster
Link to post
Share on other sites
  • 0

You need a top level module, that describes all the signals that are connected to your FPGA. 

It will then contain all you synthesiable VHDL components that make up your design, and describes how they are connected to the each other and the outside world. 

 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now