Valhalla Legends Forums Archive | Battle.net Bot Development | MBNCSUtil 1.0.4.1 (Managed BNCSUtil) released.

AuthorMessageTime
Myndfyr
No, no, I'm not just doing this to promote my stuff.

MBNCSUtil, a managed (.NET) implementation of BNCSUtil, is being released.

Shadypalm was talking to me about making a wrapper DLL for the original BNCSUtil, and having problems, when I asked (more or less) "Why don't you just make a clean implementation of it in .NET?"  We talked it over and decided I would do it.

The versioning works in such a way that the major, minor, and build numbers correspond to the version of BNCSUtil code it's based on.  Documentation at that link has more information on versioning.

[Looking back]
I had several problems with the X-SHA-1 implementation.  In an attempt to just get things done, I more or less ported (with pointers) the C version of calcHashBuf from BNCSUtil (assuming the macro USE_NEW_BSHA1 was defined 0).  I regret doing so but am confident it will work out until a better solution can be worked out.

[Planned changes]
The ROL function used in BNCSUtil, implemented in the Microsoft Visual C Runtime libraries as _lrotl, I did not implement but chose to simply import to use through P/Invoke.  This will most likely be changed in 1.0.4.2.  The other planned change is to include localization and COM support.  This will be done very soon.  Version 1.0.4.1 is therefore limited to Windows-only use (or Linux use with WINE), but version 1.0.4.2 should run on any x86-based system with the Shared Source CLI.

[On the horizon]
I may depart from implementing strictly the functionality from BNCSUtil.  One change I am considering is that of a server function -- caching the results of CheckRevision in something of a server-friendly class.  While this can already be done with the functionality provided with an external class, it might be useful to someone down the road.  I'm also considering implementing the server portions of NLS.

This code was tested with one each of Starcraft, Diablo II Retail, and Warcraft III Retail CD keys.  NLS is untested in its current implementation; however, it is based on code I previously wrote and tested previously, so it should work correctly.  However, if you choose to use it and encounter bugs, please let me know.
July 27, 2005, 12:20 AM
Kp
[quote author=MyndFyre link=topic=12336.msg122071#msg122071 date=1122423608]The ROL function used in BNCSUtil, implemented in the Microsoft Visual C Runtime libraries as _lrotl, I did not implement but chose to simply import to use through P/Invoke.  This will most likely be changed in 1.0.4.2.[/quote]

Why not just keep ROL as a macro?  Under gcc, ROL gets optimized into a roll instructon.  I've never checked, but VC probably does the same.  A reasonably decent parser/JITer should do the same, whereas an explicit invocation of the function likely will not be inlined.
July 27, 2005, 1:48 AM
Myndfyr
[quote author=Kp link=topic=12336.msg122077#msg122077 date=1122428916]
[quote author=MyndFyre link=topic=12336.msg122071#msg122071 date=1122423608]The ROL function used in BNCSUtil, implemented in the Microsoft Visual C Runtime libraries as _lrotl, I did not implement but chose to simply import to use through P/Invoke.  This will most likely be changed in 1.0.4.2.[/quote]

Why not just keep ROL as a macro?  Under gcc, ROL gets optimized into a roll instructon.  I've never checked, but VC probably does the same.  A reasonably decent parser/JITer should do the same, whereas an explicit invocation of the function likely will not be inlined.
[/quote]

Because the C# preprocessor doesn't support macros.

[edit]I'm fairly certain you know this and are attempting to use it to point out a lack of language feature....

[edit 2]I've updated to 1.0.4.2.  This changes the ROL function to be a short function call rather than a platform-invoke.  This enables Linux users with the SSCLI to use the related function.  I've also removed out the English strings and localized the assembly.
July 27, 2005, 2:26 AM
kamakazie
Here is my implementation in VB.NET of Blizzard's SHA1 ported from iago's JavaOp:

[code]
Imports System.Security.Cryptography

Namespace Bncs.Util
    Public Class BlizzardSHA
        Inherits SHA1

        Private _Buffer(1024) As Byte
        Private _Length As Integer

        Public Overrides Sub Initialize()
            _Length = 0
        End Sub

        Protected Overrides Sub HashCore(ByVal array() As Byte, ByVal ibStart As Integer, ByVal cbSize As Integer)
            If _Length + cbSize > _Buffer.Length Then
                ReDim Preserve _Buffer(2 * (_Length + cbSize))
            End If

            System.Buffer.BlockCopy(array, ibStart, _Buffer, _Length, cbSize)
            _Length += cbSize
        End Sub

        Protected Overrides Function HashFinal() As Byte()
            Dim hashBuffer(&H10 + 5 - 1) As UInteger
            ReDim Preserve _Buffer(_Length)

            hashBuffer(0) = &H67452301UI
            hashBuffer(1) = &HEFCDAB89UI
            hashBuffer(2) = &H98BADCFEUI
            hashBuffer(3) = &H10325476UI
            hashBuffer(4) = &HC3D2E1F0UI

            If _Buffer.Length Mod 4 <> 0 Then
                ReDim Preserve _Buffer(_Buffer.Length + (4 - _Buffer.Length Mod 4))
            End If

            For i As Integer = 0 To _Buffer.Length - 1 Step &H40
                Dim length As Integer = _Buffer.Length - i

                If length > &H40 Then
                    length = &H40
                End If

                System.Buffer.BlockCopy(_Buffer, i, hashBuffer, 20, length)

                If length < &H40 Then
                    Dim zeroBuffer(&H40 - length) As Byte

                    System.Buffer.BlockCopy(zeroBuffer, 0, hashBuffer, 20 + length, zeroBuffer.Length - 1)
                End If

                DataHash(hashBuffer)
            Next

            Dim hashBytes(19) As Byte

            System.Buffer.BlockCopy(hashBuffer, 0, hashBytes, 0, 20)

            Return hashBytes
        End Function

        Private Shared Sub DataHash(ByVal param() As UInteger)
            Dim buf(&H50) As UInteger
            Dim dw As UInteger
            Dim a As UInteger = param(0)
            Dim b As UInteger = param(1)
            Dim c As UInteger = param(2)
            Dim d As UInteger = param(3)
            Dim e As UInteger = param(4)
            Dim p As Integer = 0

            Array.Copy(param, 5, buf, 0, param.Length - 5)

            For i As Integer = &H10 To &H4F
                dw = CByte((buf(i - &H10) Xor buf(i - &H8) Xor buf(i - &HE) Xor buf(i - &H3)) And &HFF)

                buf(i) = (1 >> (&H20 - dw)) Or (1 << dw)
            Next

            For i As Integer = 0 To &H13
                dw = ((a << 5) Or (a >> &H1B)) + (((Not b) And d) Or (c And b)) + e + buf(p) + &H5A827999UI
                e = d
                d = c
                c = (b >> 2) Or (b << &H1E)
                b = a
                a = dw

                p += 1
            Next

            For i As Integer = 0 To &H13
                dw = (d Xor c Xor b) + e + ((a << 5) Or (a >> &H1B)) + buf(p) + &H6ED9EBA1UI
                e = d
                d = c
                c = (b >> 2) Or (b << &H1E)
                b = a
                a = dw

                p += 1
            Next

            For i As Integer = 0 To &H13
                dw = ((c And b) Or (d And c) Or (d And b)) + e + ((a << 5) Or (a >> &H1B)) + buf(p) - &H70E44324
                e = d
                d = c
                c = (b >> 2) Or (b << &H1E)
                b = a
                a = dw

                p += 1
            Next

            For i As Integer = 0 To &H13
                dw = ((a << 5) Or (a >> &H1B)) + e + (d Xor c Xor b) + buf(p) - &H359D3E2AUI
                e = d
                d = c
                c = (b >> 2) Or (b << &H1E)
                b = a
                a = dw

                p += 1
            Next

            param(0) += a
            param(1) += b
            param(2) += c
            param(3) += d
            param(4) += e
        End Sub
    End Class
End Namespace
[/code]

I don't know if that helps but a nice thing to do would to inherit from SHA1 just because it's nice to be able to change the SHA implementation dynamically depending on the product.

Edit: Removed HashPassword function.
July 27, 2005, 3:43 AM
shout
Omg ripoff of my bnethashing.dll... j/k.

*cry* Why does no one want my stuff? *cry*
July 27, 2005, 3:48 AM
Lenny
[quote]I don't know if that helps but a nice thing to do would to inherit from SHA1 just because it's nice to be able to change the SHA implementation dynamically depending on the product. [/quote]
Done...

(worked from BNCSUtil source)
July 27, 2005, 5:37 AM
Myndfyr
[quote author=dxoigmn link=topic=12336.msg122097#msg122097 date=1122435813]
I don't know if that helps but a nice thing to do would to inherit from SHA1 just because it's nice to be able to change the SHA implementation dynamically depending on the product.
[/quote]

Thanks for the input.  :)  I'll look into using it down the road.

As far as inheriting from SHA1, the most local variables you should ever have to have is 2 (if you have a local SHA1 instance and a local XSha1 instance -- but even so, XSha1 isn't implemented as an instance object), so I don't think it'll be that big of a deal.  My original XSha1 implementation was based on iago's JavaOp code -- I worked for three days to try to work out what was wrong with it and never managed to.  There were things that I didn't see I needed, like TransformBlock and such.  *shrug*
July 27, 2005, 6:06 AM
kamakazie
[quote author=Lenny link=topic=12336.msg122104#msg122104 date=1122442654]
Done...

(worked from BNCSUtil source)
[/quote]

You're not inheriting from SHA1...

[quote author=MyndFyre link=topic=12336.msg122107#msg122107 date=1122444377]
Thanks for the input.  :)  I'll look into using it down the road.

As far as inheriting from SHA1, the most local variables you should ever have to have is 2 (if you have a local SHA1 instance and a local XSha1 instance -- but even so, XSha1 isn't implemented as an instance object), so I don't think it'll be that big of a deal.  My original XSha1 implementation was based on iago's JavaOp code -- I worked for three days to try to work out what was wrong with it and never managed to.  There were things that I didn't see I needed, like TransformBlock and such.  *shrug*
[/quote]

It's true you only 2 variables but I like elegance ;). As far as extending SHA1, you only need to implement [tt]HashCore()[/tt], [tt]HashFinal()[/tt], and [tt]Initialize()[/tt]. I probably should have used the protected variables [tt]HashValue[/tt] and [tt]HashSizeValue[/tt] instead of creating my own, but that eluded me when I first wrote that.
July 27, 2005, 6:23 AM
Lenny
As far as inheritance in java goes, there's no public SHA1 class.  So I took your comment as asking for a more direct implementation of the actual SHA1 algorithm.  As far as I have seen, all implementations of XSHA1 have been radically different from standard SHA1 (but each sharing the same differences  ;)).

My XSHA1 is implemented directly from http://www.itl.nist.gov/fipspubs/fip180-1.htm.  The only difference is the incorrect shift (hence, XSHA1) and the formalities standard SHA-1 takes in preparing the message for digest.  I wrote the class for the sake of correctness as well as ease of reading for someone familar with standard SHA1.
July 27, 2005, 7:34 AM
kamakazie
[quote author=Lenny link=topic=12336.msg122111#msg122111 date=1122449660]
As far as inheritance in java goes, there's no public SHA1 class.  So I took your comment as asking for a more direct implementation of the actual SHA1 algorithm.  As far as I have seen, all implementations of XSHA1 have been radically different from standard SHA1 (but each sharing the same differences  ;)).
[/quote]

There may not be a SHA1 class, but there is a MessageDigest class which happens to be abstract and allows you to use the SHA1 algorithm via [tt]getInstance("SHA")[/tt]. So, you could inherit from that.
July 27, 2005, 10:22 AM
Kp
[quote author=MyndFyre link=topic=12336.msg122084#msg122084 date=1122431197]Because the C# preprocessor doesn't support macros.

[edit]I'm fairly certain you know this and are attempting to use it to point out a lack of language feature....

[edit 2]I've updated to 1.0.4.2.  This changes the ROL function to be a short function call rather than a platform-invoke.  This enables Linux users with the SSCLI to use the related function.  I've also removed out the English strings and localized the assembly.[/quote]

I knew Java had this terrible deficiency, but I thought Microsoft might've had the sense not to replicate that mistake.  I suppose they were forced to keep it if they wanted a Java rip-off, though. :)  Making ROL an inline function will actually get you the best of both worlds.  You get the type checking of a compiler-supported feature and the performance/space gain of not using a function call.  I suppose next you're going to tell me that C# also copied Java's braindamage about lack of implicit comparison to null when you write "if (ptr)"?
July 28, 2005, 2:28 AM
shadypalm88
[quote author=Kp link=topic=12336.msg122220#msg122220 date=1122517728] I suppose next you're going to tell me that C# also copied Java's braindamage about lack of implicit comparison to null when you write "if (ptr)"?
[/quote]Like you said, they wanted a Java rip-off... It triggers a compiler error: "Cannot implicitly convert type (object) to 'bool'".
July 28, 2005, 2:54 AM
Myndfyr
[quote author=Kp link=topic=12336.msg122220#msg122220 date=1122517728]
I suppose next you're going to tell me that C# also copied Java's braindamage about lack of implicit comparison to null when you write "if (ptr)"?
[/quote]

I know that you and Zorm share this opinion (the positive one) of implicit null comparison, but I stand by my belief that it's bad practice.
July 28, 2005, 2:59 AM
Lenny
[quote author=dxoigmn link=topic=12336.msg122114#msg122114 date=1122459728]
[quote author=Lenny link=topic=12336.msg122111#msg122111 date=1122449660]
As far as inheritance in java goes, there's no public SHA1 class.  So I took your comment as asking for a more direct implementation of the actual SHA1 algorithm.  As far as I have seen, all implementations of XSHA1 have been radically different from standard SHA1 (but each sharing the same differences  ;)).
[/quote]

There may not be a SHA1 class, but there is a MessageDigest class which happens to be abstract and allows you to use the SHA1 algorithm via [tt]getInstance("SHA")[/tt]. So, you could inherit from that.
[/quote]

True, but that wouldn't be inheriting from SHA1.  That would simply be inheriting from a class which SHA1 also inherits.
July 28, 2005, 3:11 AM
Myndfyr
[quote author=Lenny link=topic=12336.msg122226#msg122226 date=1122520268]
[quote author=dxoigmn link=topic=12336.msg122114#msg122114 date=1122459728]
[quote author=Lenny link=topic=12336.msg122111#msg122111 date=1122449660]
As far as inheritance in java goes, there's no public SHA1 class.  So I took your comment as asking for a more direct implementation of the actual SHA1 algorithm.  As far as I have seen, all implementations of XSHA1 have been radically different from standard SHA1 (but each sharing the same differences  ;)).
[/quote]

There may not be a SHA1 class, but there is a MessageDigest class which happens to be abstract and allows you to use the SHA1 algorithm via [tt]getInstance("SHA")[/tt]. So, you could inherit from that.
[/quote]

True, but that wouldn't be inheriting from SHA1.  That would simply be inheriting from a class which SHA1 also inherits.
[/quote]

You're missing the point.  In the .NET Framework, SHA1 is a class descendent from HashAlgorithm.  Deriving XSha1 from either HashAlgorithm or SHA1 would be equally valid, although it's probably more worthwhile to derive from SHA1 because it's more specific.

It appears that you can register a Provider object to act as an interface to using XSha1.  You implemented XSha1 as a descendent of MessageDigest, and then call getInstance("XSHA1") to access it.  It provides a transparent way of using XSha1 just like any other cryptographic service provider.
July 28, 2005, 3:34 AM
Lenny
My point was that inheriting SHA1 from java was not possible.  But inheriting from MessageDigest does have some great advantages.

Also, while on the topic of XSHA1, my implementation seems to generate a different hash when a blank ("") password is used.  It would be great if someone were able to create and account with a blank password to see what the client would send.

These are the 5 dwords:
0x4d3aa0ee
0x94261d5a
0x584a6f57
0x6b8d9960
0x1546c680
July 28, 2005, 4:30 AM
kamakazie
[quote author=Lenny link=topic=12336.msg122235#msg122235 date=1122525021]
My point was that inheriting SHA1 from java was not possible.  But inheriting from MessageDigest does have some great advantages.
[/quote]

I suggested MyndFyre inherit from SHA1 on the .NET framework. You then come along and post "done" and I quickly glanced over your code and didn't notice you inheriting from SHA1, much less anything, regardless of the language you were using. The point was that you should inherit from some base class given the language you were using if the language has some sort of framework, which Java does. You just didn't do you research nor read my post correctly.
July 28, 2005, 12:58 PM
Lenny
I agree that it would be better to inherit from MessageDigest.  But I initially took your original post as inheritance from the actual SHA1 algorithm.  As far as I have seen, the code I posted is the only one which inherits from the actual algorithm.  This is why I'm also mentioning the anomaly I'm getting with the SHA1 hash of "".
July 28, 2005, 8:31 PM
kamakazie
[quote author=Lenny link=topic=12336.msg122304#msg122304 date=1122582668]
I agree that it would be better to inherit from MessageDigest.  But I initially took your original post as inheritance from the actual SHA1 algorithm.  As far as I have seen, the code I posted is the only one which inherits from the actual algorithm.  This is why I'm also mentioning the anomaly I'm getting with the SHA1 hash of "".
[/quote]

My VB.NET version generates the same values as yours does.
July 28, 2005, 8:48 PM
Lenny
hashBuffer[0] = 0x67452301;
hashBuffer[1] = 0xEFCDAB89;
hashBuffer[2] = 0x98BADCFE;
hashBuffer[3] = 0x10325476;
hashBuffer[4] = 0xC3D2E1F0;

is iago's XSHA output of "".
August 1, 2005, 2:32 AM

Search