Subversion Repositories Kolibri OS

Rev

Rev 3532 | Blame | Last modification | View Log | Download | RSS feed

  1. ;    libcrash -- cryptographic hash functions
  2. ;
  3. ;    Copyright (C) 2013,2016 Ivan Baravy (dunkaist)
  4. ;
  5. ;    This program is free software: you can redistribute it and/or modify
  6. ;    it under the terms of the GNU General Public License as published by
  7. ;    the Free Software Foundation, either version 3 of the License, or
  8. ;    (at your option) any later version.
  9. ;
  10. ;    This program is distributed in the hope that it will be useful,
  11. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ;    GNU General Public License for more details.
  14. ;
  15. ;    You should have received a copy of the GNU General Public License
  16. ;    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18.  
  19. SHA3224_BLOCK_SIZE      = 144
  20. SHA3256_BLOCK_SIZE      = 136
  21. SHA3384_BLOCK_SIZE      = 104
  22. SHA3512_BLOCK_SIZE      = 72
  23. SHA3MAX_BLOCK_SIZE      = SHA3224_BLOCK_SIZE
  24.  
  25. SHA3_INIT_SIZE          = 200
  26.  
  27. SHA3224_HASH_SIZE       = 28
  28. SHA3256_HASH_SIZE       = 32
  29. SHA3384_HASH_SIZE       = 48
  30. SHA3512_HASH_SIZE       = 64
  31.  
  32. SHA3_ALIGN              = 16
  33. SHA3_ALIGN_MASK         = SHA3_ALIGN-1
  34.  
  35. struct ctx_sha3
  36.         hash            rb SHA3_INIT_SIZE
  37.                         rb SHA3_ALIGN - (SHA3_INIT_SIZE mod SHA3_ALIGN)
  38.         block           rb SHA3MAX_BLOCK_SIZE
  39.                         rb SHA3_ALIGN - (SHA3MAX_BLOCK_SIZE mod SHA3_ALIGN)
  40.         index           rd 1
  41.         block_size      rd 1
  42.         rounds_cnt      rd 1
  43.                         rd 1    ; align
  44.         ; tmp vars
  45.         C               rq 5
  46.         D               rq 5
  47. ends
  48.  
  49.  
  50. macro sha3._.rol_xor nd, ncl, ncr
  51. {
  52.         movq    mm0, [C + 8*(ncl)]
  53.         movq    mm1, mm0
  54.         psllq   mm0, 1
  55.         psrlq   mm1, 63
  56.         por     mm0, mm1
  57.         pxor    mm0, [C + 8*(ncr)]
  58.         movq    [D + 8*(nd)], mm0
  59. }
  60.  
  61. proc sha3._.theta
  62. ;locals
  63. ;        C       rq 5
  64. ;        D       rq 5
  65. ;endl
  66. C equ ebx + ctx_sha3.C
  67. D equ ebx + ctx_sha3.D
  68.  
  69. repeat 5
  70.         movq    mm0, [edi + 8*(%-1 +  0)]
  71.         pxor    mm0, [edi + 8*(%-1 +  5)]
  72.         pxor    mm0, [edi + 8*(%-1 + 10)]
  73.         pxor    mm0, [edi + 8*(%-1 + 15)]
  74.         pxor    mm0, [edi + 8*(%-1 + 20)]
  75.         movq    [C + 8*(%-1)], mm0
  76. end repeat
  77.  
  78.         sha3._.rol_xor  0, 1, 4
  79.         sha3._.rol_xor  1, 2, 0
  80.         sha3._.rol_xor  2, 3, 1
  81.         sha3._.rol_xor  3, 4, 2
  82.         sha3._.rol_xor  4, 0, 3
  83.  
  84. repeat 5
  85.         movq    mm1, [D + 8*(%-1)]
  86.         movq    mm0, mm1
  87.         pxor    mm0, [edi + 8*(%-1 +  0)]
  88.         movq    [edi + 8*(%-1 +  0)], mm0
  89.         movq    mm0, mm1
  90.         pxor    mm0, [edi + 8*(%-1 +  5)]
  91.         movq    [edi + 8*(%-1 +  5)], mm0
  92.         movq    mm0, mm1
  93.         pxor    mm0, [edi + 8*(%-1 + 10)]
  94.         movq    [edi + 8*(%-1 + 10)], mm0
  95.         movq    mm0, mm1
  96.         pxor    mm0, [edi + 8*(%-1 + 15)]
  97.         movq    [edi + 8*(%-1 + 15)], mm0
  98.         movq    mm0, mm1
  99.         pxor    mm0, [edi + 8*(%-1 + 20)]
  100.         movq    [edi + 8*(%-1 + 20)], mm0
  101. end repeat
  102.  
  103. restore C,D
  104.         ret
  105. endp
  106.  
  107.  
  108. proc sha3._.pi
  109.         movq    mm1, [edi + 8*1]
  110.         movq    mm0, [edi + 8*6]
  111.         movq    [edi + 8*1], mm0
  112.         movq    mm0, [edi + 8*9]
  113.         movq    [edi + 8*6], mm0
  114.         movq    mm0, [edi + 8*22]
  115.         movq    [edi + 8*9], mm0
  116.         movq    mm0, [edi + 8*14]
  117.         movq    [edi + 8*22], mm0
  118.         movq    mm0, [edi + 8*20]
  119.         movq    [edi + 8*14], mm0
  120.         movq    mm0, [edi + 8*2]
  121.         movq    [edi + 8*20], mm0
  122.         movq    mm0, [edi + 8*12]
  123.         movq    [edi + 8*2], mm0
  124.         movq    mm0, [edi + 8*13]
  125.         movq    [edi + 8*12], mm0
  126.         movq    mm0, [edi + 8*19]
  127.         movq    [edi + 8*13], mm0
  128.         movq    mm0, [edi + 8*23]
  129.         movq    [edi + 8*19], mm0
  130.         movq    mm0, [edi + 8*15]
  131.         movq    [edi + 8*23], mm0
  132.         movq    mm0, [edi + 8*4]
  133.         movq    [edi + 8*15], mm0
  134.         movq    mm0, [edi + 8*24]
  135.         movq    [edi + 8*4], mm0
  136.         movq    mm0, [edi + 8*21]
  137.         movq    [edi + 8*24], mm0
  138.         movq    mm0, [edi + 8*8]
  139.         movq    [edi + 8*21], mm0
  140.         movq    mm0, [edi + 8*16]
  141.         movq    [edi + 8*8], mm0
  142.         movq    mm0, [edi + 8*5]
  143.         movq    [edi + 8*16], mm0
  144.         movq    mm0, [edi + 8*3]
  145.         movq    [edi + 8*5], mm0
  146.         movq    mm0, [edi + 8*18]
  147.         movq    [edi + 8*3], mm0
  148.         movq    mm0, [edi + 8*17]
  149.         movq    [edi + 8*18], mm0
  150.         movq    mm0, [edi + 8*11]
  151.         movq    [edi + 8*17], mm0
  152.         movq    mm0, [edi + 8*7]
  153.         movq    [edi + 8*11], mm0
  154.         movq    mm0, [edi + 8*10]
  155.         movq    [edi + 8*7], mm0
  156.         movq    [edi + 8*10], mm1
  157.  
  158.         ret
  159. endp
  160.  
  161.  
  162. proc sha3._.chi
  163.  
  164.         mov     eax, 0xffffffff
  165.         movd    mm0, eax
  166.         movq    mm2, mm0
  167.         punpckldq       mm2, mm0
  168.  
  169. repeat 5
  170.         movq    mm6, [edi + 8*(0 + 5*(%-1))]
  171.         movq    mm7, [edi + 8*(1 + 5*(%-1))]
  172.  
  173.         movq    mm0, [edi + 8*(0 + 5*(%-1))]
  174.         movq    mm1, mm7
  175.         pandn   mm1, mm2
  176.         pand    mm1, [edi + 8*(2 + 5*(%-1))]
  177.         pxor    mm0, mm1
  178.         movq    [edi + 8*(0 + 5*(%-1))], mm0
  179.  
  180.         movq    mm0, [edi + 8*(1 + 5*(%-1))]
  181.         movq    mm1, [edi + 8*(2 + 5*(%-1))]
  182.         pandn   mm1, mm2
  183.         pand    mm1, [edi + 8*(3 + 5*(%-1))]
  184.         pxor    mm0, mm1
  185.         movq    [edi + 8*(1 + 5*(%-1))], mm0
  186.  
  187.         movq    mm0, [edi + 8*(2 + 5*(%-1))]
  188.         movq    mm1, [edi + 8*(3 + 5*(%-1))]
  189.         pandn   mm1, mm2
  190.         pand    mm1, [edi + 8*(4 + 5*(%-1))]
  191.         pxor    mm0, mm1
  192.         movq    [edi + 8*(2 + 5*(%-1))], mm0
  193.  
  194.         movq    mm0, [edi + 8*(3 + 5*(%-1))]
  195.         movq    mm1, [edi + 8*(4 + 5*(%-1))]
  196.         pandn   mm1, mm2
  197.         pand    mm1, mm6
  198.         pxor    mm0, mm1
  199.         movq    [edi + 8*(3 + 5*(%-1))], mm0
  200.  
  201.         movq    mm0, [edi + 8*(4 + 5*(%-1))]
  202.         movq    mm1, mm6
  203.         pandn   mm1, mm2
  204.         pand    mm1, mm7
  205.         pxor    mm0, mm1
  206.         movq    [edi + 8*(4 + 5*(%-1))], mm0
  207. end repeat
  208.         ret
  209. endp
  210.  
  211.  
  212. macro sha3._.rol_mov n, c
  213. {
  214.         movq    mm0, [edi + 8*(n)]
  215.         movq    mm1, mm0
  216.         psllq   mm0, (c)
  217.         psrlq   mm1, (64-(c))
  218.         por     mm0, mm1
  219.         movq    [edi + 8*(n)], mm0
  220. }
  221.  
  222. proc sha3._.permutation
  223.  
  224. repeat 24
  225.         stdcall sha3._.theta
  226.  
  227.         sha3._.rol_mov   1,  1
  228.         sha3._.rol_mov   2, 62
  229.         sha3._.rol_mov   3, 28
  230.         sha3._.rol_mov   4, 27
  231.         sha3._.rol_mov   5, 36
  232.         sha3._.rol_mov   6, 44
  233.         sha3._.rol_mov   7,  6
  234.         sha3._.rol_mov   8, 55
  235.         sha3._.rol_mov   9, 20
  236.         sha3._.rol_mov  10,  3
  237.         sha3._.rol_mov  11, 10
  238.         sha3._.rol_mov  12, 43
  239.         sha3._.rol_mov  13, 25
  240.         sha3._.rol_mov  14, 39
  241.         sha3._.rol_mov  15, 41
  242.         sha3._.rol_mov  16, 45
  243.         sha3._.rol_mov  17, 15
  244.         sha3._.rol_mov  18, 21
  245.         sha3._.rol_mov  19,  8
  246.         sha3._.rol_mov  20, 18
  247.         sha3._.rol_mov  21,  2
  248.         sha3._.rol_mov  22, 61
  249.         sha3._.rol_mov  23, 56
  250.         sha3._.rol_mov  24, 14
  251.  
  252.         stdcall sha3._.pi
  253.         stdcall sha3._.chi
  254.  
  255.         movq    mm0, [edi + 8*(0)]
  256.         pxor    mm0, [sha3._.round + 8*(%-1)]
  257.         movq    [edi + 8*(0)], mm0
  258. end repeat
  259.  
  260.         ret
  261. endp
  262.  
  263.  
  264. proc sha3._.init _ctx
  265.         mov     [ebx + ctx_sha3.block_size], eax
  266.         shr     eax, 3
  267.         dec     eax
  268.         mov     [ebx + ctx_sha3.rounds_cnt], eax
  269.         xor     eax, eax
  270.         lea     edi, [ebx + ctx_sha3.hash]
  271.         mov     ecx, SHA3_INIT_SIZE/4
  272.         rep     stosd
  273.         mov     [ebx + ctx_sha3.index], eax
  274.         ret
  275. endp
  276.  
  277.  
  278. proc sha3224.init _ctx
  279.         mov     ebx, [_ctx]
  280.         mov     eax, SHA3224_BLOCK_SIZE
  281.         stdcall sha3._.init
  282.         ret
  283. endp
  284.  
  285.  
  286. proc sha3256.init _ctx
  287.         mov     ebx, [_ctx]
  288.         mov     eax, SHA3256_BLOCK_SIZE
  289.         stdcall sha3._.init
  290.         ret
  291. endp
  292.  
  293.  
  294. proc sha3384.init _ctx
  295.         mov     ebx, [_ctx]
  296.         mov     eax, SHA3384_BLOCK_SIZE
  297.         stdcall sha3._.init
  298.         ret
  299. endp
  300.  
  301.  
  302. proc sha3512.init _ctx
  303.         mov     ebx, [_ctx]
  304.         mov     eax, SHA3512_BLOCK_SIZE
  305.         stdcall sha3._.init
  306.         ret
  307. endp
  308.  
  309.  
  310. proc sha3._.block _hash
  311.         mov     ecx, [ebx + ctx_sha3.rounds_cnt]
  312.         mov     edi, [_hash]
  313.  
  314.     @@:
  315.         movq    mm0, [esi + 8*ecx]
  316.         pxor    mm0, [edi + 8*ecx]
  317.         movq    [edi + 8*ecx], mm0
  318.         dec     ecx
  319.         jns     @b
  320.  
  321.         stdcall sha3._.permutation
  322.  
  323.         ret
  324. endp
  325.  
  326.  
  327. proc sha3.update _ctx, _msg, _size
  328.   .next_block:
  329.         mov     ebx, [_ctx]
  330.         mov     esi, [_msg]
  331.         mov     eax, [ebx + ctx_sha3.index]
  332.         test    eax, eax
  333.         jnz     .copy_to_buf
  334.         test    esi, SHA3_ALIGN_MASK
  335.         jnz     .copy_to_buf
  336.   .no_copy:
  337.         ; data is aligned, hash it in place without copying
  338.         mov     ebx, [_ctx]
  339.         mov     eax, [ebx + ctx_sha3.block_size]
  340.         cmp     [_size], eax
  341.         jb      .copy_quit
  342.         lea     eax, [ebx + ctx_sha3.hash]
  343.         push    ebx esi
  344.         stdcall sha3._.block, eax
  345.         pop     esi ebx
  346.         mov     eax, [ebx + ctx_sha3.block_size]
  347.         sub     [_size], eax
  348.         add     esi, [ebx + ctx_sha3.block_size]
  349.         jmp     .no_copy
  350.  
  351.   .copy_to_buf:
  352.         lea     edi, [ebx + ctx_sha3.block]
  353.         add     edi, eax
  354.         mov     ecx, [ebx + ctx_sha3.block_size]
  355.         sub     ecx, eax
  356.         cmp     [_size], ecx
  357.         jb      .copy_quit
  358.         sub     [_size], ecx
  359.         add     [_msg], ecx
  360.         add     [ebx + ctx_sha3.index], ecx
  361.         mov     eax, [ebx + ctx_sha3.block_size]
  362.         cmp     [ebx + ctx_sha3.index], eax
  363.         jb      @f
  364.         sub     [ebx + ctx_sha3.index], eax
  365.     @@:
  366.         rep     movsb
  367.         lea     eax, [ebx + ctx_sha3.hash]
  368.         lea     esi, [ebx + ctx_sha3.block]
  369.         stdcall sha3._.block, eax
  370.         jmp     .next_block
  371.  
  372.   .copy_quit:
  373.         mov     ebx, [_ctx]
  374.         lea     edi, [ebx + ctx_sha3.block]
  375.         mov     eax, [ebx + ctx_sha3.index]
  376.         add     edi, eax
  377.         mov     ecx, [_size]
  378.         add     [ebx + ctx_sha3.index], ecx
  379.         rep     movsb
  380.   .quit:
  381.         ret
  382. endp
  383.  
  384.  
  385. proc sha3.final _ctx
  386.         pushad
  387.         mov     ebx, [_ctx]
  388.         mov     eax, [ebx + ctx_sha3.index]
  389.         xor     edx, edx
  390.         mov     ecx, [ebx + ctx_sha3.block_size]
  391.         div     ecx
  392.         sub     ecx, edx
  393.         ja      @f
  394.         add     ecx, [ebx + ctx_sha3.block_size]
  395.     @@:
  396.         add     [ebx + ctx_sha3.index], ecx
  397.         mov     eax, [ebx + ctx_sha3.block_size]
  398.         cmp     [ebx + ctx_sha3.index], eax
  399.         jb      @f
  400.         sub     [ebx + ctx_sha3.index], eax
  401.     @@:
  402.  
  403.         mov     byte[edi], 0x06
  404.         inc     edi
  405.         dec     ecx
  406.         xor     eax, eax
  407.         rep     stosb
  408.         or      byte[edi - 1], 0x80
  409.  
  410.         mov     ebx, [_ctx]
  411.         lea     esi, [ebx + ctx_sha3.block]
  412.         lea     eax, [ebx + ctx_sha3.hash]
  413.         stdcall sha3._.block, eax
  414.  
  415.         mov     ebx, [_ctx]
  416.         lea     eax, [ebx + ctx_sha3.hash]
  417.         stdcall sha3._.postprocess, ebx, eax
  418.  
  419.         popad
  420.         ret
  421. endp
  422.  
  423.  
  424. proc sha3._.postprocess _ctx, _hash
  425.         emms
  426.         ret
  427. endp
  428.  
  429.  
  430. align SHA3_ALIGN
  431.  
  432. sha3._.round    dq 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,\
  433.                    0x8000000080008000, 0x000000000000808B, 0x0000000080000001,\
  434.                    0x8000000080008081, 0x8000000000008009, 0x000000000000008A,\
  435.                    0x0000000000000088, 0x0000000080008009, 0x000000008000000A,\
  436.                    0x000000008000808B, 0x800000000000008B, 0x8000000000008089,\
  437.                    0x8000000000008003, 0x8000000000008002, 0x8000000000000080,\
  438.                    0x000000000000800A, 0x800000008000000A, 0x8000000080008081,\
  439.                    0x8000000000008080, 0x0000000080000001, 0x8000000080008008
  440.  
  441.