LCOV - code coverage report
Current view: top level - src/crypto - chacha20.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 261 263 99.2 %
Date: 2022-04-21 14:51:19 Functions: 8 8 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 26 32 81.2 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2017-2019 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : // Based on the public domain implementation 'merged' by D. J. Bernstein
#       6                 :            : // See https://cr.yp.to/chacha.html.
#       7                 :            : 
#       8                 :            : #include <crypto/common.h>
#       9                 :            : #include <crypto/chacha20.h>
#      10                 :            : 
#      11                 :            : #include <string.h>
#      12                 :            : 
#      13                 : 1808975910 : constexpr static inline uint32_t rotl32(uint32_t v, int c) { return (v << c) | (v >> (32 - c)); }
#      14                 :            : 
#      15                 :            : #define QUARTERROUND(a,b,c,d) \
#      16                 :  452244120 :   a += b; d = rotl32(d ^ a, 16); \
#      17                 :  452244120 :   c += d; b = rotl32(b ^ c, 12); \
#      18                 :  452244120 :   a += b; d = rotl32(d ^ a, 8); \
#      19                 :  452244120 :   c += d; b = rotl32(b ^ c, 7);
#      20                 :            : 
#      21                 :            : static const unsigned char sigma[] = "expand 32-byte k";
#      22                 :            : static const unsigned char tau[] = "expand 16-byte k";
#      23                 :            : 
#      24                 :            : void ChaCha20::SetKey(const unsigned char* k, size_t keylen)
#      25                 :    1460028 : {
#      26                 :    1460028 :     const unsigned char *constants;
#      27                 :            : 
#      28                 :    1460028 :     input[4] = ReadLE32(k + 0);
#      29                 :    1460028 :     input[5] = ReadLE32(k + 4);
#      30                 :    1460028 :     input[6] = ReadLE32(k + 8);
#      31                 :    1460028 :     input[7] = ReadLE32(k + 12);
#      32         [ +  - ]:    1460028 :     if (keylen == 32) { /* recommended */
#      33                 :    1460028 :         k += 16;
#      34                 :    1460028 :         constants = sigma;
#      35                 :    1460028 :     } else { /* keylen == 16 */
#      36                 :          0 :         constants = tau;
#      37                 :          0 :     }
#      38                 :    1460028 :     input[8] = ReadLE32(k + 0);
#      39                 :    1460028 :     input[9] = ReadLE32(k + 4);
#      40                 :    1460028 :     input[10] = ReadLE32(k + 8);
#      41                 :    1460028 :     input[11] = ReadLE32(k + 12);
#      42                 :    1460028 :     input[0] = ReadLE32(constants + 0);
#      43                 :    1460028 :     input[1] = ReadLE32(constants + 4);
#      44                 :    1460028 :     input[2] = ReadLE32(constants + 8);
#      45                 :    1460028 :     input[3] = ReadLE32(constants + 12);
#      46                 :    1460028 :     input[12] = 0;
#      47                 :    1460028 :     input[13] = 0;
#      48                 :    1460028 :     input[14] = 0;
#      49                 :    1460028 :     input[15] = 0;
#      50                 :    1460028 : }
#      51                 :            : 
#      52                 :            : ChaCha20::ChaCha20()
#      53                 :    1693543 : {
#      54                 :    1693543 :     memset(input, 0, sizeof(input));
#      55                 :    1693543 : }
#      56                 :            : 
#      57                 :            : ChaCha20::ChaCha20(const unsigned char* k, size_t keylen)
#      58                 :       1916 : {
#      59                 :       1916 :     SetKey(k, keylen);
#      60                 :       1916 : }
#      61                 :            : 
#      62                 :            : void ChaCha20::SetIV(uint64_t iv)
#      63                 :      18316 : {
#      64                 :      18316 :     input[14] = iv;
#      65                 :      18316 :     input[15] = iv >> 32;
#      66                 :      18316 : }
#      67                 :            : 
#      68                 :            : void ChaCha20::Seek(uint64_t pos)
#      69                 :      30322 : {
#      70                 :      30322 :     input[12] = pos;
#      71                 :      30322 :     input[13] = pos >> 32;
#      72                 :      30322 : }
#      73                 :            : 
#      74                 :            : void ChaCha20::Keystream(unsigned char* c, size_t bytes)
#      75                 :    5605501 : {
#      76                 :    5605501 :     uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
#      77                 :    5605501 :     uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
#      78                 :    5605501 :     unsigned char *ctarget = nullptr;
#      79                 :    5605501 :     unsigned char tmp[64];
#      80                 :    5605501 :     unsigned int i;
#      81                 :            : 
#      82         [ -  + ]:    5605501 :     if (!bytes) return;
#      83                 :            : 
#      84                 :    5605501 :     j0 = input[0];
#      85                 :    5605501 :     j1 = input[1];
#      86                 :    5605501 :     j2 = input[2];
#      87                 :    5605501 :     j3 = input[3];
#      88                 :    5605501 :     j4 = input[4];
#      89                 :    5605501 :     j5 = input[5];
#      90                 :    5605501 :     j6 = input[6];
#      91                 :    5605501 :     j7 = input[7];
#      92                 :    5605501 :     j8 = input[8];
#      93                 :    5605501 :     j9 = input[9];
#      94                 :    5605501 :     j10 = input[10];
#      95                 :    5605501 :     j11 = input[11];
#      96                 :    5605501 :     j12 = input[12];
#      97                 :    5605501 :     j13 = input[13];
#      98                 :    5605501 :     j14 = input[14];
#      99                 :    5605501 :     j15 = input[15];
#     100                 :            : 
#     101                 :    5617029 :     for (;;) {
#     102         [ +  + ]:    5617029 :         if (bytes < 64) {
#     103                 :       3573 :             ctarget = c;
#     104                 :       3573 :             c = tmp;
#     105                 :       3573 :         }
#     106                 :    5617029 :         x0 = j0;
#     107                 :    5617029 :         x1 = j1;
#     108                 :    5617029 :         x2 = j2;
#     109                 :    5617029 :         x3 = j3;
#     110                 :    5617029 :         x4 = j4;
#     111                 :    5617029 :         x5 = j5;
#     112                 :    5617029 :         x6 = j6;
#     113                 :    5617029 :         x7 = j7;
#     114                 :    5617029 :         x8 = j8;
#     115                 :    5617029 :         x9 = j9;
#     116                 :    5617029 :         x10 = j10;
#     117                 :    5617029 :         x11 = j11;
#     118                 :    5617029 :         x12 = j12;
#     119                 :    5617029 :         x13 = j13;
#     120                 :    5617029 :         x14 = j14;
#     121                 :    5617029 :         x15 = j15;
#     122         [ +  + ]:   61787324 :         for (i = 20;i > 0;i -= 2) {
#     123                 :   56170295 :             QUARTERROUND( x0, x4, x8,x12)
#     124                 :   56170295 :             QUARTERROUND( x1, x5, x9,x13)
#     125                 :   56170295 :             QUARTERROUND( x2, x6,x10,x14)
#     126                 :   56170295 :             QUARTERROUND( x3, x7,x11,x15)
#     127                 :   56170295 :             QUARTERROUND( x0, x5,x10,x15)
#     128                 :   56170295 :             QUARTERROUND( x1, x6,x11,x12)
#     129                 :   56170295 :             QUARTERROUND( x2, x7, x8,x13)
#     130                 :   56170295 :             QUARTERROUND( x3, x4, x9,x14)
#     131                 :   56170295 :         }
#     132                 :    5617029 :         x0 += j0;
#     133                 :    5617029 :         x1 += j1;
#     134                 :    5617029 :         x2 += j2;
#     135                 :    5617029 :         x3 += j3;
#     136                 :    5617029 :         x4 += j4;
#     137                 :    5617029 :         x5 += j5;
#     138                 :    5617029 :         x6 += j6;
#     139                 :    5617029 :         x7 += j7;
#     140                 :    5617029 :         x8 += j8;
#     141                 :    5617029 :         x9 += j9;
#     142                 :    5617029 :         x10 += j10;
#     143                 :    5617029 :         x11 += j11;
#     144                 :    5617029 :         x12 += j12;
#     145                 :    5617029 :         x13 += j13;
#     146                 :    5617029 :         x14 += j14;
#     147                 :    5617029 :         x15 += j15;
#     148                 :            : 
#     149                 :    5617029 :         ++j12;
#     150         [ -  + ]:    5617029 :         if (!j12) ++j13;
#     151                 :            : 
#     152                 :    5617029 :         WriteLE32(c + 0, x0);
#     153                 :    5617029 :         WriteLE32(c + 4, x1);
#     154                 :    5617029 :         WriteLE32(c + 8, x2);
#     155                 :    5617029 :         WriteLE32(c + 12, x3);
#     156                 :    5617029 :         WriteLE32(c + 16, x4);
#     157                 :    5617029 :         WriteLE32(c + 20, x5);
#     158                 :    5617029 :         WriteLE32(c + 24, x6);
#     159                 :    5617029 :         WriteLE32(c + 28, x7);
#     160                 :    5617029 :         WriteLE32(c + 32, x8);
#     161                 :    5617029 :         WriteLE32(c + 36, x9);
#     162                 :    5617029 :         WriteLE32(c + 40, x10);
#     163                 :    5617029 :         WriteLE32(c + 44, x11);
#     164                 :    5617029 :         WriteLE32(c + 48, x12);
#     165                 :    5617029 :         WriteLE32(c + 52, x13);
#     166                 :    5617029 :         WriteLE32(c + 56, x14);
#     167                 :    5617029 :         WriteLE32(c + 60, x15);
#     168                 :            : 
#     169         [ +  + ]:    5617029 :         if (bytes <= 64) {
#     170         [ +  + ]:    5605502 :             if (bytes < 64) {
#     171         [ +  + ]:      73719 :                 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
#     172                 :       3573 :             }
#     173                 :    5605502 :             input[12] = j12;
#     174                 :    5605502 :             input[13] = j13;
#     175                 :    5605502 :             return;
#     176                 :    5605502 :         }
#     177                 :      11527 :         bytes -= 64;
#     178                 :      11527 :         c += 64;
#     179                 :      11527 :     }
#     180                 :    5605501 : }
#     181                 :            : 
#     182                 :            : void ChaCha20::Crypt(const unsigned char* m, unsigned char* c, size_t bytes)
#     183                 :      24014 : {
#     184                 :      24014 :     uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
#     185                 :      24014 :     uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
#     186                 :      24014 :     unsigned char *ctarget = nullptr;
#     187                 :      24014 :     unsigned char tmp[64];
#     188                 :      24014 :     unsigned int i;
#     189                 :            : 
#     190         [ -  + ]:      24014 :     if (!bytes) return;
#     191                 :            : 
#     192                 :      24014 :     j0 = input[0];
#     193                 :      24014 :     j1 = input[1];
#     194                 :      24014 :     j2 = input[2];
#     195                 :      24014 :     j3 = input[3];
#     196                 :      24014 :     j4 = input[4];
#     197                 :      24014 :     j5 = input[5];
#     198                 :      24014 :     j6 = input[6];
#     199                 :      24014 :     j7 = input[7];
#     200                 :      24014 :     j8 = input[8];
#     201                 :      24014 :     j9 = input[9];
#     202                 :      24014 :     j10 = input[10];
#     203                 :      24014 :     j11 = input[11];
#     204                 :      24014 :     j12 = input[12];
#     205                 :      24014 :     j13 = input[13];
#     206                 :      24014 :     j14 = input[14];
#     207                 :      24014 :     j15 = input[15];
#     208                 :            : 
#     209                 :      36022 :     for (;;) {
#     210         [ +  + ]:      36022 :         if (bytes < 64) {
#     211                 :            :             // if m has fewer than 64 bytes available, copy m to tmp and
#     212                 :            :             // read from tmp instead
#     213         [ +  + ]:     880542 :             for (i = 0;i < bytes;++i) tmp[i] = m[i];
#     214                 :      24014 :             m = tmp;
#     215                 :      24014 :             ctarget = c;
#     216                 :      24014 :             c = tmp;
#     217                 :      24014 :         }
#     218                 :      36022 :         x0 = j0;
#     219                 :      36022 :         x1 = j1;
#     220                 :      36022 :         x2 = j2;
#     221                 :      36022 :         x3 = j3;
#     222                 :      36022 :         x4 = j4;
#     223                 :      36022 :         x5 = j5;
#     224                 :      36022 :         x6 = j6;
#     225                 :      36022 :         x7 = j7;
#     226                 :      36022 :         x8 = j8;
#     227                 :      36022 :         x9 = j9;
#     228                 :      36022 :         x10 = j10;
#     229                 :      36022 :         x11 = j11;
#     230                 :      36022 :         x12 = j12;
#     231                 :      36022 :         x13 = j13;
#     232                 :      36022 :         x14 = j14;
#     233                 :      36022 :         x15 = j15;
#     234         [ +  + ]:     396242 :         for (i = 20;i > 0;i -= 2) {
#     235                 :     360220 :             QUARTERROUND( x0, x4, x8,x12)
#     236                 :     360220 :             QUARTERROUND( x1, x5, x9,x13)
#     237                 :     360220 :             QUARTERROUND( x2, x6,x10,x14)
#     238                 :     360220 :             QUARTERROUND( x3, x7,x11,x15)
#     239                 :     360220 :             QUARTERROUND( x0, x5,x10,x15)
#     240                 :     360220 :             QUARTERROUND( x1, x6,x11,x12)
#     241                 :     360220 :             QUARTERROUND( x2, x7, x8,x13)
#     242                 :     360220 :             QUARTERROUND( x3, x4, x9,x14)
#     243                 :     360220 :         }
#     244                 :      36022 :         x0 += j0;
#     245                 :      36022 :         x1 += j1;
#     246                 :      36022 :         x2 += j2;
#     247                 :      36022 :         x3 += j3;
#     248                 :      36022 :         x4 += j4;
#     249                 :      36022 :         x5 += j5;
#     250                 :      36022 :         x6 += j6;
#     251                 :      36022 :         x7 += j7;
#     252                 :      36022 :         x8 += j8;
#     253                 :      36022 :         x9 += j9;
#     254                 :      36022 :         x10 += j10;
#     255                 :      36022 :         x11 += j11;
#     256                 :      36022 :         x12 += j12;
#     257                 :      36022 :         x13 += j13;
#     258                 :      36022 :         x14 += j14;
#     259                 :      36022 :         x15 += j15;
#     260                 :            : 
#     261                 :      36022 :         x0 ^= ReadLE32(m + 0);
#     262                 :      36022 :         x1 ^= ReadLE32(m + 4);
#     263                 :      36022 :         x2 ^= ReadLE32(m + 8);
#     264                 :      36022 :         x3 ^= ReadLE32(m + 12);
#     265                 :      36022 :         x4 ^= ReadLE32(m + 16);
#     266                 :      36022 :         x5 ^= ReadLE32(m + 20);
#     267                 :      36022 :         x6 ^= ReadLE32(m + 24);
#     268                 :      36022 :         x7 ^= ReadLE32(m + 28);
#     269                 :      36022 :         x8 ^= ReadLE32(m + 32);
#     270                 :      36022 :         x9 ^= ReadLE32(m + 36);
#     271                 :      36022 :         x10 ^= ReadLE32(m + 40);
#     272                 :      36022 :         x11 ^= ReadLE32(m + 44);
#     273                 :      36022 :         x12 ^= ReadLE32(m + 48);
#     274                 :      36022 :         x13 ^= ReadLE32(m + 52);
#     275                 :      36022 :         x14 ^= ReadLE32(m + 56);
#     276                 :      36022 :         x15 ^= ReadLE32(m + 60);
#     277                 :            : 
#     278                 :      36022 :         ++j12;
#     279         [ -  + ]:      36022 :         if (!j12) ++j13;
#     280                 :            : 
#     281                 :      36022 :         WriteLE32(c + 0, x0);
#     282                 :      36022 :         WriteLE32(c + 4, x1);
#     283                 :      36022 :         WriteLE32(c + 8, x2);
#     284                 :      36022 :         WriteLE32(c + 12, x3);
#     285                 :      36022 :         WriteLE32(c + 16, x4);
#     286                 :      36022 :         WriteLE32(c + 20, x5);
#     287                 :      36022 :         WriteLE32(c + 24, x6);
#     288                 :      36022 :         WriteLE32(c + 28, x7);
#     289                 :      36022 :         WriteLE32(c + 32, x8);
#     290                 :      36022 :         WriteLE32(c + 36, x9);
#     291                 :      36022 :         WriteLE32(c + 40, x10);
#     292                 :      36022 :         WriteLE32(c + 44, x11);
#     293                 :      36022 :         WriteLE32(c + 48, x12);
#     294                 :      36022 :         WriteLE32(c + 52, x13);
#     295                 :      36022 :         WriteLE32(c + 56, x14);
#     296                 :      36022 :         WriteLE32(c + 60, x15);
#     297                 :            : 
#     298         [ +  + ]:      36022 :         if (bytes <= 64) {
#     299         [ +  - ]:      24014 :             if (bytes < 64) {
#     300         [ +  + ]:     880542 :                 for (i = 0;i < bytes;++i) ctarget[i] = c[i];
#     301                 :      24014 :             }
#     302                 :      24014 :             input[12] = j12;
#     303                 :      24014 :             input[13] = j13;
#     304                 :      24014 :             return;
#     305                 :      24014 :         }
#     306                 :      12008 :         bytes -= 64;
#     307                 :      12008 :         c += 64;
#     308                 :      12008 :         m += 64;
#     309                 :      12008 :     }
#     310                 :      24014 : }

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a