OpenCores
URL https://opencores.org/ocsvn/simpletousesha2/simpletousesha2/trunk

Subversion Repositories simpletousesha2

[/] [simpletousesha2/] [trunk/] [src/] [sha2.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 shadow7853
library ieee;
2
use ieee.std_logic_1164.all;
3
--use ieee.std_logic_misc.all;
4
use ieee.numeric_std.all;
5
library work;
6
use work.shaPkg.all;
7
 
8
entity sha2 is
9
  port (
10
    clk         : in  std_logic;
11
    rst         : in  std_logic;
12
    chunk       : in  std_logic_vector(0 to CW-1);
13
    len         : in  std_logic_vector(0 to CLENBIT-1);
14
    load        : in  std_logic;
15
    --hash        : out std_logic_vector(0 to OS-1);
16
    hash        : out std_logic_vector(0 to WW-1);
17
    valid       : out std_logic
18
    );
19
 
20
end sha2;
21
 
22
architecture hash of sha2 is
23
 
24
  component stepCount
25
    port (
26
    cnt            : out integer range 0 to STMAX-1;
27
    clk            : in  std_logic;
28
    rst            : in  std_logic
29
    );
30
  end component;
31
 
32
  component outCount
33
   port (
34
   cnt            : out integer range 0 to WOUT-1;
35
   clk            : in  std_logic;
36
   en             : in  std_logic
37
   );
38
  end component;
39
 
40
  component romk
41
    port (
42
    addr           : in  integer range 0 to STMAX-1;
43
    k              : out std_logic_vector (0 to WW-1)
44
    );
45
  end component;
46
 
47
  signal k        : std_logic_vector(0 to WW-1);
48
 
49
  signal new_w    : unsigned(0 to WW-1);  -- nuova word del blocco Wt per t <= 15
50
  signal cal_w    : unsigned(0 to WW-1);  -- nuova word calcolata Wt per t > 15
51
  signal w        : unsigned(0 to WW-1);  -- word da utilizzare Wt
52
  signal wnd      : unsigned(0 to BS-1);  -- registro a scorrimento da Wt-16 a Wt-1
53
  signal buf      : unsigned(0 to BS-1);  -- buffer blocco precedente
54
 
55
  signal h_vld    : std_logic;  -- hash valida
56
  signal blk_vld  : std_logic;  -- blocco elaborato
57
 
58
  signal loaded   : std_logic;  -- ho caricato
59
  signal loading  : std_logic;  -- sto caricando
60
  signal load_pad : std_logic;  -- sto caricando
61
  signal load_rst : std_logic;  -- comincia un nuovo messaggio
62
 
63
  signal step_rst : std_logic;                      -- comincio a elaborare un nuovo blocco
64
  signal step     : integer range 0 to STMAX-1;     -- contatore step (sha-224/256 = 64)
65
  signal w_out    : integer range 0 to WOUT-1;      -- contatore out word's  (sha-224 = 7, 256 = 8)
66
 
67
  signal blk_num  : unsigned(0 to MSGBIT-LENBIT-1); -- numero di blocchi da elaborare
68
  signal blk_ok   : unsigned(0 to MSGBIT-LENBIT-1); -- numero di blocchi elaborati
69
  signal msg_len  : unsigned(0 to MSGBIT-1);        -- lunghezza messaggio
70
 
71
  -- Registri dell'algoritmo SHA-2
72
 
73
  signal a        : unsigned(0 to WW-1);
74
  signal b        : unsigned(0 to WW-1);
75
  signal c        : unsigned(0 to WW-1);
76
  signal d        : unsigned(0 to WW-1);
77
  signal e        : unsigned(0 to WW-1);
78
  signal f        : unsigned(0 to WW-1);
79
  signal g        : unsigned(0 to WW-1);
80
  signal h        : unsigned(0 to WW-1);
81
 
82
  signal a_2      : unsigned(0 to WW-1);
83
  signal b_2      : unsigned(0 to WW-1);
84
  signal c_2      : unsigned(0 to WW-1);
85
  signal d_2      : unsigned(0 to WW-1);
86
  signal e_2      : unsigned(0 to WW-1);
87
  signal f_2      : unsigned(0 to WW-1);
88
  signal g_2      : unsigned(0 to WW-1);
89
  signal h_2      : unsigned(0 to WW-1);
90
 
91
  signal s0       : unsigned(0 to WW-1); -- sigma0
92
  signal s1       : unsigned(0 to WW-1); -- sigma1
93
  signal maj      : unsigned(0 to WW-1);
94
  signal ch       : unsigned(0 to WW-1);
95
 
96
  signal th0      : unsigned(0 to WW-1); -- theta0
97
  signal th1      : unsigned(0 to WW-1); -- theta1
98
 
99
  --signal t1       : unsigned(0 to WW-1); -- T1
100
  --signal t2       : unsigned(0 to WW-1); -- T2
101
 
102
  signal h0       : unsigned(0 to WW-1);
103
  signal h1       : unsigned(0 to WW-1);
104
  signal h2       : unsigned(0 to WW-1);
105
  signal h3       : unsigned(0 to WW-1);
106
  signal h4       : unsigned(0 to WW-1);
107
  signal h5       : unsigned(0 to WW-1);
108
  signal h6       : unsigned(0 to WW-1);
109
  signal h7       : unsigned(0 to WW-1);
110
 
111
  -- FSM
112
  signal first    : std_logic;
113
  signal first2   : std_logic;
114
  type state_type is (s_idle, s_load, s_add_block, s_padding, s_compute);
115
  signal state    : state_type;
116
 
117
begin  -- hash
118
 
119
  -----------------------------------------------------------------------------  
120
  -- CONNESSIONI PERMANENTI PER CALCOLO DI OGNI STEP
121
  -----------------------------------------------------------------------------
122
 
123
  rom0             : romk
124
  port map (
125
    addr           => step,
126
    k              => k
127
  );
128
 
129
  step_count       : stepCount
130
  port map (
131
    cnt            => step,
132
    clk            => clk,
133
    rst            => step_rst
134
  );
135
 
136
  out_count       : outCount
137
  port map (
138
    cnt            => w_out,
139
    clk            => clk,
140
    en             => h_vld
141
  );
142
 
143
  -- Connessione digest -> hash, per sha-256/512 OS == ISS per 224/384 OS < ISS
144
  --hash  <= std_logic_vector(h0) & std_logic_vector(h1) & std_logic_vector(h2) & std_logic_vector(h3) & std_logic_vector(h4) & std_logic_vector(h5) & std_logic_vector(h6) & std_logic_vector(h7); -- (0 to OS-1);       
145
  with w_out select hash <= std_logic_vector(h0) when 0,
146
                            std_logic_vector(h1) when 1,
147
                            std_logic_vector(h2) when 2,
148
                            std_logic_vector(h3) when 3,
149
                            std_logic_vector(h4) when 4,
150
                            std_logic_vector(h5) when 5,
151
                            std_logic_vector(h6) when 6,
152
                            std_logic_vector(h7) when others;
153
  valid <= h_vld;
154
 
155
  --s0  <= (a ror 2) xor (a ror 13) xor (a ror 22);
156
  --maj <= (a and b) xor (a and c) xor (b and c);
157
  --s1  <= (e ror 6) xor (e ror 11) xor (e ror 25);
158
  --ch  <= (e and f) xor ((not e)and g);
159
 
160
  s0  <= ((a + a_2)  ror 2) xor ((a + a_2) ror 13) xor ((a + a_2) ror 22);
161
  maj <= ((a + a_2) and (b + b_2)) xor ((a + a_2) and (c + c_2)) xor ((b + b_2) and (c + c_2));
162
  s1  <= ((e + e_2) ror 6) xor ((e + e_2) ror 11) xor ((e + e_2) ror 25);
163
  ch  <= ((e + e_2) and (f + f_2)) xor ((not (e + e_2))and (g + g_2));
164
 
165
  -- tetha0(Wt-15) == tetha0(W1) sulla finestra mobile
166
  th0 <= (wnd(WW to 2*WW-1) ror 7) xor (wnd(WW to 2*WW-1) ror 18) xor (wnd(WW to 2*WW-1) srl 3);
167
  -- tetha1(Wt-2) == tetha0(W14) sulla finestra mobile                                                                                                                  
168
  th1 <= (wnd(14*WW to 15*WW-1) ror 17) xor (wnd(14*WW to 15*WW-1) ror 19) xor (wnd(14*WW to 15*WW-1) srl 10);
169
 
170
  -- Wt = tetha1(Wt-15) + Wt-7 + tetha0(Wt-2) + Wt-16 === Wt = tetha1(W1) + W9 + tetha0(Wt14) + W0 sulla finestra mobile
171
  cal_w <= th1 + wnd(9*WW to 10*WW-1) + th0 + wnd(0 to WW-1);
172
 
173
  -- NON SERVONO: Riduzione datapath
174
  --t1 <= h + s1 + ch + k[i] + w[i]                                                                                
175
  --t1 <= h + s1 + ch + unsigned(k) + w;
176
  --t2 <= s0 + maj
177
  --t2 <= s0 + maj;
178
 
179
  -- VARIABILI CONTROLLER
180
 
181
  with state select load_pad <= '1'  when s_add_block,
182
                                '1'  when s_padding,
183
                                                                '1'  when s_load,
184
                                                                load when others;
185
 
186
  load_rst  <= (loaded xor load_pad) and load_pad;   -- ORA STO CARICANDO MA NEL CICLO PASSATO NO == PARTENZA
187
  step_rst  <=  load_rst or rst;                     -- RESET CONTATORE STEP SE E' IN RESET O COMINCIA UN NUOVO CARICAMENTO
188
 
189
  -----------------------------------------------------------------------------  
190
  -- SEGNALI PRIMO BLOCCO: Conversione bloccata per il riempimento buffer
191
  -----------------------------------------------------------------------------
192
 
193
  first_blk: process (clk)
194
  begin
195
    if rising_edge(clk) then
196
      if rst = '1' then
197
        first <= '0';
198
        first2 <= '0';
199
      else
200
                first2  <= first;
201
                if load_rst = '1' then
202
          first <= '1';
203
        elsif step = STMAX-1 and first = '1' then
204
          first <= '0';
205
                end if;
206
      end if;
207
    end if;
208
  end process;
209
 
210
  -----------------------------------------------------------------------------  
211
  -- CONTROLLER NUMERO BLOCCHI
212
  -----------------------------------------------------------------------------    
213
 
214
  blk_counter: process (clk)
215
  begin
216
    if (rising_edge(clk)) then
217
      if ((load_rst or rst) = '1') then
218
 
219
            blk_num(MSGBIT-LENBIT-1)      <= '1';
220
        blk_num(0 to MSGBIT-LENBIT-2) <= (others => '0');
221
        blk_ok                        <= (others => '0');
222
            h_vld                         <= '0';
223
 
224
      elsif blk_ok < blk_num then
225
 
226
                -- caricato un nuovo blocco del messaggio
227
                if (load_pad = '1' and blk_vld = '1') then
228
                        blk_num <= blk_num + 1;
229
                end if;
230
 
231
                -- elaborato un blocco del messaggio
232
                if (first = '0' and step = STMAX-1) then
233
                        blk_ok  <= blk_ok + 1;
234
                end if;
235
 
236
          elsif state = s_compute and blk_ok = blk_num then
237
 
238
                if h_vld = '0' then
239
                  h_vld <= '1';
240
                end if;
241
 
242
          -- dopo aver mandato in out tutte le word della hash, metto h_vld = '0'
243
      elsif w_out = WOUT-1 then
244
            h_vld   <= '0';
245
                --blk_num <= (others => '0'); -- inibisce ulteriore modifica di h_vld
246
          end if;
247
 
248
    end if;
249
  end process;
250
 
251
  -----------------------------------------------------------------------------  
252
  -- SETTA blk_vld SE NON E' IN RESET E HA CARICATO UN BLOCCO PER INTERO
253
  -----------------------------------------------------------------------------  
254
 
255
  blk_validity: process (clk)
256
  begin
257
    if (rising_edge(clk)) then
258
      if ((load_rst or rst) = '1') then
259
        blk_vld <= '0';
260
      elsif (step = STMAX-1) then
261
        blk_vld <= '1';
262
      else
263
        blk_vld <= '0';
264
      end if;
265
    end if;
266
  end process;
267
 
268
  --------------------------------------------------------------------------------------------------  
269
  -- FASE 0: PREPROCESSING - RIEMPIMENTO BUFFER + CONTROLLER STATO + INSERIMENTO PADDING E LUNGHEZZA
270
  --------------------------------------------------------------------------------------------------
271
 
272
  p0_fill_buffer_and_padding: process (clk)
273
  variable len_i : integer range 0 to MSGBIT-1;
274
  variable clen : integer range 0 to CW;
275
  variable c    : unsigned(0 to CW-1);
276
  begin
277
    if rising_edge(clk) then
278
      if rst = '1' then                      -- inizializza al reset
279
        buf     <= (others => '0');
280
        msg_len <= (others => '0');
281
        state   <= s_idle;
282
      else
283
                if load = '1' then
284
 
285
                  state <= s_load;
286
                  clen := to_integer(unsigned(len));
287
          if clen = CW then
288
            c          := unsigned(chunk);   -- Carico messaggio
289
            msg_len    <= msg_len + CW;      -- chunk pieno
290
          else                               -- chunk partiale carico messaggio con padding di 1 e vado in stato padding direttamente
291
            c := (others => '0');
292
                        c(0 to clen-1) := unsigned(chunk(0 to clen-1));
293
                        c(clen) := '1';
294
            msg_len    <= msg_len + clen;        -- chunk partiale (per forza ultimo)
295
            if (step+2)*CW + 1 >= BS-MSGBIT then -- SE >= 448 devo aggiungere un intero blocco di padding
296
                          state   <= s_add_block;
297
                        else
298
                  state   <= s_padding;
299
                        end if;
300
          end if;
301
 
302
        elsif state = s_load then            -- se msg_len multipla di CW aggiungo un chunk di padding
303
                                                         -- con bit 1 e zeri e poi vado in stato padding
304
          c(0)         := '1';
305
          c(1 to CW-1) := (others => '0');
306
          if (step+2)*CW + 1 >= BS-MSGBIT then   -- SE >= 448 devo aggiungere un intero blocco di padding
307
                        state <= s_add_block;
308
                  else
309
            state <= s_padding;
310
                  end if;
311
 
312
                elsif state = s_add_block then       -- finisco il blocco con il padding aggiungendone un altro
313
 
314
                  c := (others => '0');
315
                  if step = STMAX-1 then
316
                    state <= s_padding;
317
                  end if;
318
 
319
                elsif state = s_padding then         -- faccio padding di zeri fino agli ultimi 64 bit x la lunghezza
320
 
321
              if step = STMAX-1 then             -- alla fine mette in IDLE
322
                    state <= s_compute;
323
                        c     := (others => '0');
324
                  elsif step >= STMAX-4 and step < STMAX-2 then -- aggiunge chunk per chunk la lunghezza
325
                        len_i := step*CW-(BS-MSGBIT-2*CW);
326
                        c     := msg_len(len_i to len_i+CW-1);
327
                  else
328
                    c     := (others => '0');
329
                  end if;
330
 
331
                else                                 -- re-inizializza a conversione effettuata
332
 
333
          buf     <= (others => '0');
334
                  msg_len <= (others => '0');
335
                  c       := (others => '0');
336
 
337
                  if state = s_compute and h_vld = '1' then
338
                          state <= s_idle;
339
                  end if;
340
 
341
                end if;
342
 
343
                -- shift del buffer
344
 
345
                buf(BS-CW to BS-1)   <= c;
346
                buf(0 to BS-CW-1)    <= buf(CW to BS-1);
347
 
348
      end if;
349
    end if;
350
  end process;
351
 
352
  --------------------------------------------------------------------------------------------------
353
  -- CONTROLLER CARICAMENTO WORD
354
  --------------------------------------------------------------------------------------------------
355
 
356
  fill_word: process (clk)
357
  begin
358
    if (rising_edge(clk)) then
359
      if (rst = '1') then
360
                loaded  <= '0';
361
        loading <= '0';
362
        new_w   <= (others => '0');
363
      else
364
        loaded  <= loading;           -- SE HA CARICATO UNA WORD
365
                loading <= load_pad;          -- SE STA CARICANDO UNA WORD
366
 
367
                -- LA NUOVA WORD IN INPUT (tiene conto del ciclo di clock per il caricamento)
368
            -- il buffer si riempie a CW bit per volta, leggo a WW, word corrente si sposta           <--   CREA PROBLEMA DI CONNESSIONI? FORSE MIGLIORABILE
369
 
370
                if step = STMAX-2 then
371
                  new_w   <= buf(0 to WW-1);
372
                elsif step = STMAX-1 then
373
                  new_w   <= buf(WW-CW to (WW-CW)+WW-1);
374
                elsif step > 14 then
375
                  new_w   <= (others => '0');
376
        else
377
                  new_w   <= buf((step+2)*(WW-CW) to (step+2)*(WW-CW)+WW-1);
378
                end if;
379
      end if;
380
    end if;
381
  end process;
382
 
383
  --------------------------------------------------------------------------------------------------
384
  -- FASE 1: RIEMPIMENTO REGISTRO A SCORRIMENTO: ESPANSIONE
385
  --------------------------------------------------------------------------------------------------
386
 
387
  p1_expansion: process (clk)
388
  begin
389
    if (rising_edge(clk)) then
390
      if (rst = '1') then
391
        w                  <= (others => '0');
392
        wnd                <= (others => '0');
393
      elsif step < WBLK-1 or step = STMAX-1 then  -- i da 1 a 16
394
        w                  <= new_w;
395
        wnd(BS-WW to BS-1) <= new_w;
396
        wnd(0 to BS-WW-1)  <= wnd(WW to BS-1);    -- shift della finestra corrente
397
      else                                        -- i da 17 a 64
398
        w                  <= cal_w;
399
        wnd(BS-WW to BS-1) <= cal_w;
400
        wnd(0 to BS-WW-1)  <= wnd(WW to BS-1);    -- shift della finestra corrente
401
      end if;
402
    end if;
403
  end process;
404
 
405
  --------------------------------------------------------------------------------------------------
406
  -- FASE 2: LOOP DI COMPRESSIONE
407
  --------------------------------------------------------------------------------------------------
408
 
409
  p2_compression: process (clk)
410
  begin
411
    if (rising_edge(clk)) then
412
 
413
          -- inizializza a inizio messaggio
414
      if (load_rst or rst) = '1' then
415
        a  <=  (others => '0');
416
        b  <=  (others => '0');
417
        c  <=  (others => '0');
418
        d  <=  (others => '0');
419
        e  <=  (others => '0');
420
        f  <=  (others => '0');
421
        g  <=  (others => '0');
422
        h  <=  (others => '0');
423
        a_2  <=  (others => '0');
424
        b_2  <=  (others => '0');
425
        c_2  <=  (others => '0');
426
        d_2  <=  (others => '0');
427
        e_2  <=  (others => '0');
428
        f_2  <=  (others => '0');
429
        g_2  <=  (others => '0');
430
        h_2  <=  (others => '0');
431
 
432
      -- AI CICLI SUCCESSIVI IMPOSTO I REGISTRI CON LE FUNZIONI CORRETTI
433
      else
434
                -- al primo blocco la compressione č disabilitata (riempimento buffer)
435
        if first = '0' then
436
                  -- T1 e T2 sono state espanse direttamente in a ed e
437
                  -- T1 ==  h + s1(e) + ch(e, f, g) + k(t) + W(t)
438
                  -- T2 ==  s0(a) + maj(a, b, c)
439
 
440
                  -- ulteriore riduzione datapath, (a-g)_2 contengono 0 in tutti gli step tranne l'ultimo
441
                  -- quando contengono il digest corrente e vengono direttamente sommati alle variabili (a-g)
442
                  -- cosė da eliminare il ritardo di propagazione di un ciclo che sfaserebbe il sincronismo
443
                  -- con il caricamento multiblocco
444
 
445
          h  <=  g + g_2;
446
          g  <=  f + f_2;
447
          f  <=  e + e_2;
448
          e  <=  d + d_2 + h + h_2 + s1 + ch + unsigned(k) + w;   -- e  <=  d + T1;
449
          d  <=  c + c_2;
450
          c  <=  b + b_2;
451
          b  <=  a + a_2;
452
          a  <=  h + h_2 + s1 + ch + unsigned(k) + w + s0 + maj;  -- a  <= T1 + T2;
453
        end if;
454
 
455
                -- imposta all'ultimo step (a-g)_2 con il digest
456
        if step = STMAX-1 then
457
          a_2  <=  h0;
458
          b_2  <=  h1;
459
          c_2  <=  h2;
460
          d_2  <=  h3;
461
          e_2  <=  h4;
462
          f_2  <=  h5;
463
          g_2  <=  h6;
464
          h_2  <=  h7;
465
        else
466
          a_2  <=  (others => '0');
467
          b_2  <=  (others => '0');
468
          c_2  <=  (others => '0');
469
          d_2  <=  (others => '0');
470
          e_2  <=  (others => '0');
471
          f_2  <=  (others => '0');
472
          g_2  <=  (others => '0');
473
          h_2  <=  (others => '0');
474
        end if;
475
      end if;
476
    end if;
477
  end process;
478
 
479
  --------------------------------------------------------------------------------------------------
480
  -- FASE 3: ELABORAZIONE (aggiornamento) DIGEST - HASH
481
  --------------------------------------------------------------------------------------------------
482
 
483
  p3_digest_computation: process (clk)
484
  begin
485
    if (rising_edge(clk)) then
486
 
487
      -- reset a inizio messaggio
488
      if ((load_rst or rst) = '1') then
489
        h0   <= HASH0;
490
        h1   <= HASH1;
491
        h2   <= HASH2;
492
        h3   <= HASH3;
493
        h4   <= HASH4;
494
        h5   <= HASH5;
495
        h6   <= HASH6;
496
        h7   <= HASH7;
497
 
498
          -- nuova H cambia a ogni blocco elaborato e rimane fissa quando l'hash č valido
499
      elsif (blk_vld = '1' and first2 = '0') then
500
        h0   <= a + h0;
501
        h1   <= b + h1;
502
        h2   <= c + h2;
503
        h3   <= d + h3;
504
        h4   <= e + h4;
505
        h5   <= f + h5;
506
        h6   <= g + h6;
507
        h7   <= h + h7;
508
      end if;
509
 
510
    end if;
511
  end process;
512
 
513
 end hash;

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.