flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > SHA-256 in fasm

Author
Thread Post new topic Reply to topic
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 09 Nov 2018, 13:21
Hi,

I've implemented SHA-256 in protmode fasm with the same API as OpenSSL (init/update/final).
I haven't unrolled the sha loop, but I've used a lookup table to avoid root calculation.
Compiled code is small (958 bytes), source licensed under MIT:
https://gitlab.com/bztsrc/sha256asm

Cheers,
bzt
Post 09 Nov 2018, 13:21
View user's profile Send private message Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 10 Nov 2018, 23:15
Excellent!

This is nicely done for a super-small SHA256 implementation. The one I wrote for my HeavyThing library ( here ) is about 10x larger in size. I like your coding style, well done Smile

_________________
2 Ton Digital - https://2ton.com.au/
Post 10 Nov 2018, 23:15
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 12 Nov 2018, 10:30
Hi,

Thanks! I've checked your code, nicely done! You have a full, universal implementation! Mine is heaviliy optimized for 256 and one context only, because I wanted to use it in a bootloader. Unlike your's, mine is for a specific case only, no wonder it's much smaller.

Cheers,
bzt
Post 12 Nov 2018, 10:30
View user's profile Send private message Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 413
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 12 Nov 2018, 23:31
I found bug in sha_upd()
Code:
            ; IN: ESI = buffer,ECX = length. Clobbers EAX,EDI.
sha_upd:    mov         edi,dword [sha_l]
            add         edi,sha_d
            ; for(;len--;d++) {
            ; ctx->d[ctx->l++]=*d;
.next:      movsb
            inc         byte [sha_l]
            ; if(ctx->l==64) {
            cmp         byte [sha_l],64
            jne         @f
            ; sha256_t(ctx);
            call        sha_final.sha_t
            ; SHA_ADD(ctx->b[0],ctx->b[1],512);
            add         dword [sha_b],512
            adc         dword [sha_b+4],0
            ; ctx->l=0;
            mov         byte [sha_l],0
            ; }
@@:         dec         ecx
            jnz         sha_upd;.next        ;bug in this line
            ret    

_________________
smaller is better
Post 12 Nov 2018, 23:31
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 14 Nov 2018, 11:43
Hi,

First of all, thank you very much for checking out my code!

Why do you think that's a bug? Why should the code reload the edi register on every iteration?
I think the bug is more likely not setting edi to sha_d when sha_l overflows, isn't it? I'll create a test case specially for that, and come back to you with the results.

Thank you again for noticing!
bzt

EDIT: you were right! As it turned out all my test vectors were shorter than 64 bytes, so I haven't noticed that bug! My mistake. Now that I've also tested with "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" (length 896 bits), the problem is fixed!

Playing around with NIST test vectors, I've found another one that didn't work: the empty message. Honestly I use sha for hashing disk encryption passwords, so it never popped into my mind to test it against an empty message... Anyway, I've fixed that too! Smile

Just for the records, those fixes added 9 bytes to the code, so now it's 967 bytes long.
Post 14 Nov 2018, 11:43
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 22 Dec 2020, 13:45
I may have found an error when hashing a string between 56 and 63 characters long (including 56 and 63). I'll try to fix it. If anyone fixes the bug, please post a fix. P.S. I think it is in the procedure " sha_final:"
Post 22 Dec 2020, 13:45
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 22 Dec 2020, 14:29
Hi WinLego,

Thanks for checking out! Why do you think it's not working? What are the expected result and actual result? Do you have a test vector that I can test with?

Is the relevant code in line 122? It should fill up the remaining buffer with zeros between sha->l (the hash length, not the string's length) and 63. Otherwise there's nothing specific to 56 and 63 in "sha_final".
Code:
            cmp         cl, 56
            jae         @f
            neg         ecx
            add         ecx, 63
            xor         al, al
            repnz       stosb
            jmp         .padded    

Thank you for helping me to improve the code!

Cheers,
bzt
Post 22 Dec 2020, 14:29
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 22 Dec 2020, 14:59
A little later, I will send a program in which I test and compare the work of two algorithms.

IDE Dev-Cpp: https://yadi.sk/d/7vJs2xn1DoJcCg[/url]


Description:
Filesize: 53.75 KB
Viewed: 18738 Time(s)

p_04.png


Description:
Filesize: 16.53 KB
Viewed: 18740 Time(s)

p_03.png


Description:
Download
Filename: 04_08_S.rar
Filesize: 76.11 KB
Downloaded: 783 Time(s)


_________________
I'm looking for someone to program with
Post 22 Dec 2020, 14:59
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 22 Dec 2020, 17:47
Hi,

Can you just copy'n'paste (or upload) the message and the expected checksum here in textual form? The point is that I could save the message in a file as-is bit-by-bit. I can't use pictures as strings, and frankly I'm not certain what "Take the Hash SHA-256" supposed to be, as it's much less than 56 bytes it surely can't be the input, right?

Btw,
Code:
$ echo -n "Take the Hash SHA-256" | sha256sum
85f2ecff4abda64395f73d71416dc81f2e320cb676102d14991e7f43d865f01f  -    
So both hex numbers on your screenshot are invalid. You probably have some padding issues maybe?

I've tried your attachment too, but unrar (UNRAR 6.00 beta 1 freeware Copyright (c) 1993-2020 Alexander Roshal) says it cannot be parsed and uncompressed. If I try to open it using MC, the archive is empty. Could you use zip perhaps? Or just upload the message file in question?

What I can say is, that I've tested my implementation with all the NIST test vectors, and it was okay. FYI I validate checksums for passwords in Asm generated by this C implementation, so far all checksums matched (but that still doesn't mean it couldn't have some bugs left).

Thanks!
bzt
Post 22 Dec 2020, 17:47
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 22 Dec 2020, 18:13
thanks for your reply. Using Your code, I learn to program in Assembly language and slowly understand the hashing algorithm. I am very glad that the algorithm does not contain errors. So I must have made a mistake somewhere. I want to bring my code to a working state and will post it here if I fix everything.

https://youtu.be/2NZ3Je-9sro


Description: 7z
Download
Filename: 04_08_S.7z
Filesize: 55.69 KB
Downloaded: 752 Time(s)


_________________
I'm looking for someone to program with
Post 22 Dec 2020, 18:13
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 22 Dec 2020, 19:06
WinLego wrote:
thanks for your reply. Using Your code, I learn to program in Assembly language and slowly understand the hashing algorithm. I am very glad that the algorithm does not contain errors. So I must have made a mistake somewhere. I want to bring my code to a working state and will post it here if I fix everything.
Thanks, good to hear! About using my code in C++, I couldn't figure out where you call it exactly, but you'll need a C++ ABI wrapper for sure. My code is for 32 bit only, and expects the inputs in certain registers (not the same as C++ uses for function arguments). Also from your Makefile I was unable to tell if you're using 64 bit or 32 bit (the Lego/sha256/Asm directory contains sources for both). If you need a portable solution that works for both, I'd suggest to copy'n'paste my C version instead into your C++ code.

You can also find my sha256 here, where I've licensed it under MIT, and it was also tested as a drop-in replacement for OpenSSL's SHA implementation.

Cheers,
bzt
Post 22 Dec 2020, 19:06
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 22 Dec 2020, 20:36
I have a 32-bit project. Thank you for the link to Your code (in C). Tomorrow I will think about whether I can use it in my project.


Last edited by WinLego on 07 Jan 2021, 14:31; edited 1 time in total
Post 22 Dec 2020, 20:36
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 07 Jan 2021, 13:10
Happy New Year! I redid the test, but the error still occurs. For example, this string will be incorrectly hashed:
Code:
sz3[123]  = "_14 characters,  30 characters, 45 characters, 49,           63",      //  error !!!
             _14 characters,  30 characters, 45 characters, 49,           63

     dc1fe257d98251bb6960711f1f63d9cf2706424f3b1d9490e4922df2b06af142  =  true (http://crypt-online.ru/crypts/sha256/)    


[/img]


Description:
Filesize: 54.5 KB
Viewed: 18429 Time(s)

p_00_01.png


Description: The Dev-Cpp console project. FASM code in the form of an object file.
Download
Filename: 00_04.rar
Filesize: 11.52 KB
Downloaded: 717 Time(s)


_________________
I'm looking for someone to program with
Post 07 Jan 2021, 13:10
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 11 Jan 2021, 11:50
Happy New Year to you too!

Thanks for the feedback and the test vector! Now that I have a message with a bad output I can take a look and debug! Btw, I read the gitlab issues more often Smile

Cheers,
bzt
Post 11 Jan 2021, 11:50
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 11 Jan 2021, 12:00
I cannot refuse to use your idea (algorithm SHA-256 implemented in assembler). It's very fast, compact and cool! But I cannot cope with the error myself. Not enough knowledge of the algorithm and assembler.

_________________
I'm looking for someone to program with
Post 11 Jan 2021, 12:00
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 11 Jan 2021, 16:10
WinLego wrote:
I cannot refuse to use your idea (algorithm SHA-256 implemented in assembler). It's very fast, compact and cool!
Thanks! But it could be even more compact and faster if you run it on newer processors using the hardware-accelerated SHA instructions Wink

WinLego wrote:
But I cannot cope with the error myself. Not enough knowledge of the algorithm and assembler.
Never mind! Describing the issue and providing a detailed way on how to reproduce the problem is enough! That's all I can ask for!

I've figured it out, and I've updated the repo with the fix. Please give it a try and see if it works for you too! Btw the fix added 3 more bytes to the code, so now it's 970 bytes in total.

Cheers,
bzt
Post 11 Jan 2021, 16:10
View user's profile Send private message Reply with quote
WinLego



Joined: 22 Dec 2020
Posts: 7
WinLego 12 Jan 2021, 17:33
Thank you for the long-awaited corrections and link. Yesterday I tested only on one test - the error disappeared. I console myself with the thought that finding errors is also a help. Together, we brought the code closer to perfection. Smile
Post 12 Jan 2021, 17:33
View user's profile Send private message Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 77
bzt 12 Jan 2021, 19:46
WinLego wrote:
Thank you for the long-awaited corrections and link.
Sorry that you had to wait almost a month. I usually reply more rapidly to gitlab issues. I had to be able to reproduce the exact error first in order to fix it, and I also had other projects to pay attention to (I had a release in the meantime for one).

WinLego wrote:
Yesterday I tested only on one test - the error disappeared. I console myself with the thought that finding errors is also a help. Together, we brought the code closer to perfection. Smile
I have several decades of experience in development as a coder as well as a project manager. One thing that I have learned during this time is that no matter how hard they try, the people writing the code can never test it sufficiently (applies to me too). Therefore having testers and listening to their feedback is very very important, I'd say the most important part of creating good quality software.

So if you have any more problems, just let me know!

Cheers,
bzt
Post 12 Jan 2021, 19:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.