Add Trivium RNG (to be tested).
This commit is contained in:
		
							parent
							
								
									654a70d8a0
								
							
						
					
					
						commit
						3ddce8a100
					
				|  | @ -0,0 +1,182 @@ | ||||||
|  | -- | ||||||
|  | --  Pseudo Random Number Generator "Trivium". | ||||||
|  | -- | ||||||
|  | --  Author: Joris van Rantwijk <joris@jorisvr.nl> | ||||||
|  | -- | ||||||
|  | --  This is a pseudo-random number generator in synthesizable VHDL. | ||||||
|  | --  The generator produces up to 64 new random bits on every clock cycle. | ||||||
|  | -- | ||||||
|  | --  The algorithm "Trivium" is by Christophe De Canniere and Bart Preneel. | ||||||
|  | --  See also: | ||||||
|  | --  C. De Canniere, B. Preneel, "Trivium Specifications", (TODO URL). | ||||||
|  | -- | ||||||
|  | --  The generator requires an 80-bit key and an 80-bit initialization | ||||||
|  | --  vector. Defaults for these values must be supplied at compile time | ||||||
|  | --  and will be used to initialize the generator at reset. The generator | ||||||
|  | --  also supports re-keying at run time. | ||||||
|  | -- | ||||||
|  | --  After reset and after re-seeding, at least 4*288 clock cycles are needed | ||||||
|  | --  before valid random data appears on the output. | ||||||
|  | -- | ||||||
|  | --  NOTE: This generator is designed to produce up to 2**64 bits | ||||||
|  | --        of secure random data. If more than 2**64 bits are generated | ||||||
|  | --        with the same key and IV, it becomes inceasingly likely that | ||||||
|  | --        the output contains patterns and correlations. | ||||||
|  | -- | ||||||
|  | 
 | ||||||
|  | -- | ||||||
|  | --  Copyright (C) 2016 Joris van Rantwijk | ||||||
|  | -- | ||||||
|  | --  This code is free software; you can redistribute it and/or | ||||||
|  | --  modify it under the terms of the GNU Lesser General Public | ||||||
|  | --  License as published by the Free Software Foundation; either | ||||||
|  | --  version 2.1 of the License, or (at your option) any later version. | ||||||
|  | -- | ||||||
|  | --  See <https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html> | ||||||
|  | -- | ||||||
|  | 
 | ||||||
|  | library ieee; | ||||||
|  | use ieee.std_logic_1164.all; | ||||||
|  | use ieee.numeric_std.all; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | entity rng_trivium is | ||||||
|  | 
 | ||||||
|  |     generic ( | ||||||
|  |         -- Number of output bits per clock cycle. | ||||||
|  |         num_bits:   integer range 1 to 64; | ||||||
|  | 
 | ||||||
|  |         -- Default key. | ||||||
|  |         init_key:   std_logic_vector(79 downto 0); | ||||||
|  | 
 | ||||||
|  |         -- Default initialization vector. | ||||||
|  |         init_iv:    std_logic_vector(79 downto 0) ); | ||||||
|  | 
 | ||||||
|  |     port ( | ||||||
|  | 
 | ||||||
|  |         -- Clock, rising edge active. | ||||||
|  |         clk:        in  std_logic; | ||||||
|  | 
 | ||||||
|  |         -- Synchronous reset, active high. | ||||||
|  |         rst:        in  std_logic; | ||||||
|  | 
 | ||||||
|  |         -- High to request re-seeding of the generator. | ||||||
|  |         reseed:     in  std_logic; | ||||||
|  | 
 | ||||||
|  |         -- New key value (must be valid when reseed = '1'). | ||||||
|  |         in_key:     in  std_logic_vector(79 downto 0); | ||||||
|  | 
 | ||||||
|  |         -- New initialization vector (must be valid when reseed = '1'). | ||||||
|  |         in_iv:      in  std_logic_vector(79 downto 0); | ||||||
|  | 
 | ||||||
|  |         -- High when the user accepts the current random data word | ||||||
|  |         -- and requests new random data for the next clock cycle. | ||||||
|  |         out_ready:  in  std_logic; | ||||||
|  | 
 | ||||||
|  |         -- High when valid random data is available on the output. | ||||||
|  |         -- This signal is low during the first 4*288 clock cycle after reset | ||||||
|  |         -- and after re-seeding, and high in all other cases. | ||||||
|  |         out_valid:  out std_logic; | ||||||
|  | 
 | ||||||
|  |         -- Random output data (valid when out_valid = '1'). | ||||||
|  |         -- A new random word appears after every rising clock edge | ||||||
|  |         -- where out_ready = '1'. | ||||||
|  |         out_data:   out std_logic_vector(num_bits-1 downto 0) ); | ||||||
|  | 
 | ||||||
|  | end entity; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | architecture trivium_arch of rng_trivium is | ||||||
|  | 
 | ||||||
|  |     -- Fixed bit strings to fill up initial state after reseeding. | ||||||
|  |     constant zeros13:   std_logic_vector(12 downto 0)  := (others => '0'); | ||||||
|  |     constant zeros4:    std_logic_vector(3 downto 0)   := (others => '0'); | ||||||
|  |     constant zeros108:  std_logic_vector(107 downto 0) := (others => '0'); | ||||||
|  |     constant ones3:     std_logic_vector(2 downto 0)   := (others => '1'); | ||||||
|  | 
 | ||||||
|  |     -- Internal state of RNG. | ||||||
|  |     signal reg_state:       std_logic_vector(287 downto 0) := | ||||||
|  |         ones3 & zeros108 & zeros4 & init_iv & zeros13 & init_key; | ||||||
|  | 
 | ||||||
|  |     signal reg_valid_wait:  unsigned(10 downto 0) := (others => '0'); | ||||||
|  | 
 | ||||||
|  |     -- Output register. | ||||||
|  |     signal reg_valid:       std_logic := '0'; | ||||||
|  |     signal reg_output:      std_logic_vector(num_bits-1 downto 0); | ||||||
|  | 
 | ||||||
|  | begin | ||||||
|  | 
 | ||||||
|  |     -- Drive output signal. | ||||||
|  |     out_valid   <= reg_valid; | ||||||
|  |     out_data    <= reg_output; | ||||||
|  | 
 | ||||||
|  |     -- Synchronous process. | ||||||
|  |     process (clk) is | ||||||
|  |         variable t1, t2, t3: std_logic_vector(num_bits-1 downto 0); | ||||||
|  |     begin | ||||||
|  |         if rising_edge(clk) then | ||||||
|  | 
 | ||||||
|  |             -- Determine valid output state. | ||||||
|  |             -- Delay by 4*288 clock cycles after re-seeding. | ||||||
|  |             if reg_valid_wait = 4*288 then | ||||||
|  |                 reg_valid   <= '1'; | ||||||
|  |             end if; | ||||||
|  | 
 | ||||||
|  |             if reg_valid = '0' then | ||||||
|  |                 reg_valid_wait  <= reg_valid_wait + 1; | ||||||
|  |             end if; | ||||||
|  | 
 | ||||||
|  |             if out_ready = '1' or reg_valid = '0' then | ||||||
|  | 
 | ||||||
|  |                 -- Prepare output word. | ||||||
|  |                 t1 := reg_state(66-1 downto 66-num_bits) xor | ||||||
|  |                       reg_state(93-1 downto 93-num_bits); | ||||||
|  |                 t2 := reg_state(162-1 downto 162-num_bits) xor | ||||||
|  |                       reg_state(177-1 downto 177-num_bits); | ||||||
|  |                 t3 := reg_state(243-1 downto 243-num_bits) xor | ||||||
|  |                       reg_state(288-1 downto 288-num_bits); | ||||||
|  | 
 | ||||||
|  |                 reg_output <= t1 xor t2 xor t3; | ||||||
|  | 
 | ||||||
|  |                 -- Update internal state. | ||||||
|  |                 t1 := t1 xor (reg_state(91-1 downto 91-num_bits) and | ||||||
|  |                               reg_state(92-1 downto 92-num_bits)) xor | ||||||
|  |                              reg_state(171-1 downto 171-num_bits); | ||||||
|  |                 t2 := t2 xor (reg_state(175-1 downto 175-num_bits) and | ||||||
|  |                               reg_state(176-1 downto 176-num_bits)) xor | ||||||
|  |                              reg_state(264-1 downto 264-num_bits); | ||||||
|  |                 t3 := t3 xor (reg_state(286-1 downto 286-num_bits) and | ||||||
|  |                               reg_state(287-1 downto 287-num_bits)) xor | ||||||
|  |                              reg_state(69-1 downto 69-num_bits); | ||||||
|  | 
 | ||||||
|  |                 reg_state(93-1 downto 0) <= | ||||||
|  |                     reg_state(93-1-num_bits downto 0) & t3; | ||||||
|  |                 reg_state(177-1 downto 94-1) <= | ||||||
|  |                     reg_state(177-1-num_bits downto 94-1) & t1; | ||||||
|  |                 reg_state(288-1 downto 178-1) <= | ||||||
|  |                     reg_state(288-1-num_bits downto 178-1) & t2; | ||||||
|  | 
 | ||||||
|  |             end if; | ||||||
|  | 
 | ||||||
|  |             -- Re-seed function. | ||||||
|  |             if reseed = '1' then | ||||||
|  |                 reg_valid       <= '0'; | ||||||
|  |                 reg_valid_wait  <= (others => '0'); | ||||||
|  |                 reg_state       <= | ||||||
|  |                     ones3 & zeros108 & zeros4 & in_iv & zeros13 & in_key; | ||||||
|  |             end if; | ||||||
|  | 
 | ||||||
|  |             -- Synchronous reset. | ||||||
|  |             if rst = '1' then | ||||||
|  |                 reg_valid       <= '0'; | ||||||
|  |                 reg_valid_wait  <= (others => '0'); | ||||||
|  |                 reg_state       <= | ||||||
|  |                     ones3 & zeros108 & zeros4 & init_iv & zeros13 & init_key; | ||||||
|  |                 reg_output      <= (others => '0'); | ||||||
|  |             end if; | ||||||
|  | 
 | ||||||
|  |         end if; | ||||||
|  |     end process; | ||||||
|  | 
 | ||||||
|  | end architecture; | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue