/*------------------------------------------------------------------------- Grostl 256-bit core File name : grostl_256.v Version : Version 1.0 Created : Feb/18/2010 Last update : Feb/18/2010 Desgined by : Toshihiro Katashita Copyright (C) 2010 AIST By using this code, you agree to the following terms and conditions. This code is copyrighted by AIST ("us"). Permission is hereby granted to copy, reproduce, redistribute or otherwise use this code as long as: there is no monetary profit gained specifically from the use or reproduction of this code, it is not sold, rented, traded or otherwise marketed, and this copyright notice is included prominently in any copy made. We shall not be liable for any damages, including without limitation direct, indirect, incidental, special or consequential damages arising from the use of this code. When you publish any results arising from the use of this code, we will appreciate it if you can cite our webpage (http://www.rcis.aist.go.jp/special/SASEBO/). -------------------------------------------------------------------------*/ //================================================ GROSTL_256 module GROSTL_256 (msg, msg_load, msg_end, hash, hash_init, busy, clk, rstn); //------------------------------------------------ input [511:0] msg; // Message input msg_load; // Load message input msg_end; // End of message input hash_init; // Initialize hash output [255:0] hash; // Hash output busy; // Busy input clk, rstn; // Clock and reset //------------------------------------------------ reg [511:0] p, q, m, h; wire [511:0] pin, pout, qin, qout; reg [3:0] round; reg [1:0] st; parameter isP = 1'b1; parameter isQ = 1'b0; //------------------------------------------------ Message path always @(posedge clk or negedge rstn) if (~rstn) m <= 512'h0; else if (msg_load) m <= msg; else if (round==4'hA) m <= 512'h0; // Q assign qin = (round==4'h0)? m : q; GROSTL_PERMUTATION_256 perm_Q (.x(qin), .y(qout), .round({4'h0,round}), .sel(isQ)); always @(posedge clk or negedge rstn) if (~rstn) q <= 512'h0; else q <= qout; //------------------------------------------------ Hash path always @(posedge clk or negedge rstn) if (~rstn) h <= 512'h0; else if (hash_init) h <= {496'h0,16'h0100}; else if (round==4'hA) if (st==2'b10) h <= h ^ p; else h <= h ^ p ^ q; assign hash = h[255:0]; // P assign pin = (round==4'h0)? h ^ m : p; GROSTL_PERMUTATION_256 perm_P (.x(pin), .y(pout), .round({4'h0,round}), .sel(isP)); always @(posedge clk or negedge rstn) if (~rstn) p <= 512'h0; else p <= pout; //------------------------------------------------ Controller always @(posedge clk or negedge rstn) if (~rstn) round <= 4'hF; else if (msg_load) round <= 4'h0; else if ((round==4'hB)&(st==2'b10)) round <= 4'h0; else if (~&round) round <= round + 4'h1; always @(posedge clk or negedge rstn) if (~rstn) st <= 2'b00; // Wait else if (msg_load) if (msg_end) st <= 2'b11; // F with EOM else st <= 2'b01; // F else if (round==4'hA) if (st==2'b11) st <= 2'b10; // Omega else st <= 2'b00; // Wait assign busy = |st; endmodule // GROSTL_256 //================================================ GROSTL_PERMUTATION_256 module GROSTL_PERMUTATION_256 (x, y, round, sel); //------------------------------------------------ input [511:0] x; // Input message output [511:0] y; // Output input [3:0] round; // Round input sel; // 0:P , 1:Q //------------------------------------------------ wire [63:0] ar0, ar1, ar2, ar3, ar4, ar5, ar6, ar7; wire [63:0] sb0, sb1, sb2, sb3, sb4, sb5, sb6, sb7; wire [63:0] sf0, sf1, sf2, sf3, sf4, sf5, sf6, sf7; wire [63:0] mb0, mb1, mb2, mb3, mb4, mb5, mb6, mb7; //------------------------------------------------ //---------------- AddRoundConstant assign ar0 = (sel)? {(x[511:504] ^ {4'h0,round}), x[503:448]}: {x[511:456], (x[455:448] ^ {4'h0,round} ^ 8'hFF)} ; assign ar1 = x[447:384]; assign ar2 = x[383:320]; assign ar3 = x[319:256]; assign ar4 = x[255:192]; assign ar5 = x[191:128]; assign ar6 = x[127: 64]; assign ar7 = x[ 63: 0]; //---------------- SubBytes SubBytes_8 sbox00 (.x(ar0), .y(sb0)); SubBytes_8 sbox01 (.x(ar1), .y(sb1)); SubBytes_8 sbox02 (.x(ar2), .y(sb2)); SubBytes_8 sbox03 (.x(ar3), .y(sb3)); SubBytes_8 sbox04 (.x(ar4), .y(sb4)); SubBytes_8 sbox05 (.x(ar5), .y(sb5)); SubBytes_8 sbox06 (.x(ar6), .y(sb6)); SubBytes_8 sbox07 (.x(ar7), .y(sb7)); //---------------- ShiftBytes assign sf0 = {sb0[63:56], sb1[55:48], sb2[47:40], sb3[39:32], sb4[31:24], sb5[23:16], sb6[15: 8], sb7[ 7: 0]}; assign sf1 = {sb1[63:56], sb2[55:48], sb3[47:40], sb4[39:32], sb5[31:24], sb6[23:16], sb7[15: 8], sb0[ 7: 0]}; assign sf2 = {sb2[63:56], sb3[55:48], sb4[47:40], sb5[39:32], sb6[31:24], sb7[23:16], sb0[15: 8], sb1[ 7: 0]}; assign sf3 = {sb3[63:56], sb4[55:48], sb5[47:40], sb6[39:32], sb7[31:24], sb0[23:16], sb1[15: 8], sb2[ 7: 0]}; assign sf4 = {sb4[63:56], sb5[55:48], sb6[47:40], sb7[39:32], sb0[31:24], sb1[23:16], sb2[15: 8], sb3[ 7: 0]}; assign sf5 = {sb5[63:56], sb6[55:48], sb7[47:40], sb0[39:32], sb1[31:24], sb2[23:16], sb3[15: 8], sb4[ 7: 0]}; assign sf6 = {sb6[63:56], sb7[55:48], sb0[47:40], sb1[39:32], sb2[31:24], sb3[23:16], sb4[15: 8], sb5[ 7: 0]}; assign sf7 = {sb7[63:56], sb0[55:48], sb1[47:40], sb2[39:32], sb3[31:24], sb4[23:16], sb5[15: 8], sb6[ 7: 0]}; //---------------- MixBytes MixBytes_8 mbytes00 (.x(sf0), .y(mb0)); MixBytes_8 mbytes01 (.x(sf1), .y(mb1)); MixBytes_8 mbytes02 (.x(sf2), .y(mb2)); MixBytes_8 mbytes03 (.x(sf3), .y(mb3)); MixBytes_8 mbytes04 (.x(sf4), .y(mb4)); MixBytes_8 mbytes05 (.x(sf5), .y(mb5)); MixBytes_8 mbytes06 (.x(sf6), .y(mb6)); MixBytes_8 mbytes07 (.x(sf7), .y(mb7)); assign y = {mb0, mb1, mb2, mb3, mb4, mb5, mb6, mb7}; endmodule // GROSTL_PERMUTATION_256 //================================================ SubBytes_8 module SubBytes_8 (x, y); //------------------------------------------------ input [63:0] x; output [63:0] y; //------------------------------------------------ SubBytes_Composite Sbox00 (.x(x[63:56]), .y(y[63:56])); SubBytes_Composite Sbox01 (.x(x[55:48]), .y(y[55:48])); SubBytes_Composite Sbox02 (.x(x[47:40]), .y(y[47:40])); SubBytes_Composite Sbox03 (.x(x[39:32]), .y(y[39:32])); SubBytes_Composite Sbox04 (.x(x[31:24]), .y(y[31:24])); SubBytes_Composite Sbox05 (.x(x[23:16]), .y(y[23:16])); SubBytes_Composite Sbox06 (.x(x[15: 8]), .y(y[15: 8])); SubBytes_Composite Sbox07 (.x(x[ 7: 0]), .y(y[ 7: 0])); endmodule // SubBytes_8 //================================================ SubBytes_Composite module SubBytes_Composite (x, y); input [7:0] x; output [7:0] y; //------------------------------------------------ wire [7:0] a, b; //------------------------------------------------ assign a = {x[5] ^ x[7], x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[6] ^ x[7], x[2] ^ x[3] ^ x[5] ^ x[7], x[1] ^ x[2] ^ x[3] ^ x[5] ^ x[7], x[1] ^ x[2] ^ x[6] ^ x[7], x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[7], x[1] ^ x[4] ^ x[6], x[0] ^ x[1] ^ x[6]}; SubBytes_GFinv_Composite gfinv (.x(a), .y(b)); assign y = { b[2] ^ b[3] ^ b[7], ~b[4] ^ b[5] ^ b[6] ^ b[7], ~b[2] ^ b[7], b[0] ^ b[1] ^ b[4] ^ b[7], b[0] ^ b[1] ^ b[2], b[0] ^ b[2] ^ b[3] ^ b[4] ^ b[5] ^ b[6], ~b[0] ^ b[7], ~b[0] ^ b[1] ^ b[2] ^ b[6] ^ b[7]}; endmodule // SubBytes_Composite //================================================ SubBytes_Composite module SubBytes_GFinv_Composite(x, y); //------------------------------------------------ input [7:0] x; output [7:0] y; //------------------------------------------------ wire [8:0] da, db, dx, dy, va, tp, tn; wire [3:0] u, v; wire [4:0] mx; wire [5:0] my; //------------------------------------------------ assign da = {x[3], x[2] ^ x[3], x[2], x[1] ^ x[3], x[0] ^ x[1] ^ x[2] ^ x[3], x[0] ^ x[2], x[1], x[0] ^ x[1], x[0]}; assign db = {x[7], x[6] ^ x[7], x[6], x[5] ^ x[7], x[4] ^ x[5] ^ x[6] ^ x[7], x[4] ^ x[6], x[5], x[4] ^ x[5], x[4]}; assign va = {v[3], v[2] ^ v[3], v[2], v[1] ^ v[3], v[0] ^ v[1] ^ v[2] ^ v[3], v[0] ^ v[2], v[1], v[0] ^ v[1], v[0]}; assign dx = da ^ db; assign dy = da & dx; assign tp = va & dx; assign tn = va & db; assign u = {dy[0] ^ dy[1] ^ dy[3] ^ dy[4] ^ x[4] ^ x[5] ^ x[6], dy[0] ^ dy[2] ^ dy[3] ^ dy[5] ^ x[4] ^ x[7], dy[0] ^ dy[1] ^ dy[7] ^ dy[8] ^ x[7], dy[0] ^ dy[2] ^ dy[6] ^ dy[7] ^ x[6] ^ x[7]}; assign y = {tn[0] ^ tn[1] ^ tn[3] ^ tn[4], tn[0] ^ tn[2] ^ tn[3] ^ tn[5], tn[0] ^ tn[1] ^ tn[7] ^ tn[8], tn[0] ^ tn[2] ^ tn[6] ^ tn[7], tp[0] ^ tp[1] ^ tp[3] ^ tp[4], tp[0] ^ tp[2] ^ tp[3] ^ tp[5], tp[0] ^ tp[1] ^ tp[7] ^ tp[8], tp[0] ^ tp[2] ^ tp[6] ^ tp[7]}; //---------------- GF(2^2^2) Inverter assign mx = {mx[0] ^ mx[1] ^ u[2], mx[0] ^ mx[2] ^ u[3], u[1] & (u[1] ^ u[3]), (u[0] ^ u[1]) & (u[0] ^ u[1] ^ u[2] ^ u[3]), u[0] & (u[0] ^ u[2])}; assign my = {~(mx[4] & u[3]), ~(mx[3] & (u[2] ^ u[3])), ~((mx[3] ^ mx[4]) & u[2]), ~(mx[4] & (u[1] ^ u[3])), ~(mx[3] & (u[0] ^ u[1] ^ u[2] ^ u[3])), ~((mx[3] ^ mx[4]) & (u[0] ^ u[2]))}; assign v = {my[3] ^ my[4], my[3] ^ my[5], my[0] ^ my[1], my[0] ^ my[2]}; endmodule // SubBytes_GFinv_Composite //================================================ MixBytes_8 module MixBytes_8(x, y); //------------------------------------------------ input [63:0] x; output [63:0] y; //------------------------------------------------ MixBytes mb00 (.x(x), .y(y[63:56])); MixBytes mb01 (.x({x[55:0],x[63:56]}), .y(y[55:48])); MixBytes mb02 (.x({x[47:0],x[63:48]}), .y(y[47:40])); MixBytes mb03 (.x({x[39:0],x[63:40]}), .y(y[39:32])); MixBytes mb04 (.x({x[31:0],x[63:32]}), .y(y[31:24])); MixBytes mb05 (.x({x[23:0],x[63:24]}), .y(y[23:16])); MixBytes mb06 (.x({x[15:0],x[63:16]}), .y(y[15: 8])); MixBytes mb07 (.x({x[ 7:0],x[63: 8]}), .y(y[ 7: 0])); endmodule // MixBytes_8 //================================================ MixBytes module MixBytes(x, y); //------------------------------------------------ input [63:0] x; output [7:0] y; //------------------------------------------------ assign y = mul_2(x[63:56]) ^ mul_2(x[55:48]) ^ mul_2(x[47:40]) ^ x[47:40] ^ mul_4(x[39:32]) ^ mul_4(x[31:24]) ^ x[31:24] ^ mul_2(x[23:16]) ^ x[23:16] ^ mul_4(x[15: 8]) ^ x[15: 8] ^ mul_4(x[ 7: 0]) ^ x[ 7: 0] ^ mul_2(x[ 7: 0]); //---------------- mul_4 function [7:0] mul_4; input [7:0] din; begin mul_4[7] = din[5]; mul_4[6] = din[4]; mul_4[5] = din[3] ^ din[7]; mul_4[4] = din[2] ^ din[6] ^ din[7]; mul_4[3] = din[1] ^ din[6]; mul_4[2] = din[0] ^ din[7]; mul_4[1] = din[6] ^ din[7]; mul_4[0] = din[6]; end endfunction //---------------- mul_2 function [7:0] mul_2; input [7:0] din; begin mul_2[7] = din[6]; mul_2[6] = din[5]; mul_2[5] = din[4]; mul_2[4] = din[3] ^ din[7]; mul_2[3] = din[2] ^ din[7]; mul_2[2] = din[1]; mul_2[1] = din[0] ^ din[7]; mul_2[0] = din[7]; end endfunction endmodule // MixBytes