//====================================================================== // // chacha_qr.v // ----------- // Verilog 2001 implementation of the stream cipher ChaCha. // This is the combinational QR logic as a separade module to allow // us to build versions of the cipher with 1, 2, 4 and even 8 // parallel qr functions. // // // Author: Joachim Strombergson // Copyright (c) 2011, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // - Neither the name of the NORDUnet nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //====================================================================== module chacha_qr( input wire clk, input wire reset_n, input wire [31 : 0] a, input wire [31 : 0] b, input wire [31 : 0] c, input wire [31 : 0] d, output wire [31 : 0] a_prim, output wire [31 : 0] b_prim, output wire [31 : 0] c_prim, output wire [31 : 0] d_prim ); //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- reg [31 : 0] a0_reg; reg [31 : 0] a0_new; // reg [31 : 0] a1_reg; // reg [31 : 0] a1_new; // reg [31 : 0] c0_reg; // reg [31 : 0] c0_new; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- reg [31 : 0] internal_a_prim; reg [31 : 0] internal_b_prim; reg [31 : 0] internal_c_prim; reg [31 : 0] internal_d_prim; //---------------------------------------------------------------- // Concurrent connectivity for ports. //---------------------------------------------------------------- assign a_prim = internal_a_prim; assign b_prim = internal_b_prim; assign c_prim = internal_c_prim; assign d_prim = internal_d_prim; //---------------------------------------------------------------- // reg_update //---------------------------------------------------------------- always @ (posedge clk) begin : reg_update if (!reset_n) begin a0_reg <= 32'h0; // a1_reg <= 32'h0; // c0_reg <= 32'h0; end else begin a0_reg <= a0_new; // a1_reg <= a1_new; // c0_reg <= c0_new; end end // reg_update //---------------------------------------------------------------- // qr // // The actual quarterround function. //---------------------------------------------------------------- always @* begin : qr reg [31 : 0] a0; reg [31 : 0] a1; reg [31 : 0] b0; reg [31 : 0] b1; reg [31 : 0] b2; reg [31 : 0] b3; reg [31 : 0] c0; reg [31 : 0] c1; reg [31 : 0] d0; reg [31 : 0] d1; reg [31 : 0] d2; reg [31 : 0] d3; a0 = a + b; a0_new = a0; d0 = d ^ a0; d1 = {d0[15 : 0], d0[31 : 16]}; c0 = c + d1; // c0_new = c0; b0 = b ^ c0; b1 = {b0[19 : 0], b0[31 : 20]}; a1 = a0 + b1; // a1_new = a1; d2 = d1 ^ a1; d3 = {d2[23 : 0], d2[31 : 24]}; c1 = c0 + d3; b2 = b1 ^ c1; b3 = {b2[24 : 0], b2[31 : 25]}; internal_a_prim = a1; internal_b_prim = b3; internal_c_prim = c1; internal_d_prim = d3; end // qr endmodule // chacha_qr //====================================================================== // EOF chacha_qr.v //======================================================================