-
-
Save rgchris/7b37ea1facde391149dac4b16f1ce7c0 to your computer and use it in GitHub Desktop.
MySQL v10 Password Hashing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rebol [ | |
Title: "Routine to Hash a Password for MySQL" | |
Date: 15-Jul-2020 | |
Author: "Christopher Ross-Gill" | |
] | |
int-32: func [value [integer!]] [ | |
debin [be +/- 4] enbin [be + 4] value | |
] | |
int-64: func [value [integer!]] [ | |
; 2147483647 and+ debin [be + 4] enbin [be +/- 4] value | |
; debin [be + 4] #{7FFFFFFF} and enbin [be +/- 4] value | |
either negative? value [abs value + 2147483647] [value] ; to integer! #7FFFFFFF | |
] | |
shift-32: func [value [integer!]] [ | |
int-32 4294967295 and+ shift/logical value 8 ; to integer! #FFFFFFFF | |
] | |
step: func [ | |
hash [block!] | |
upper [integer!] | |
][ | |
hash/1: modulo int-64 int-32 (hash/1 * 3 + hash/2) upper | |
hash/2: modulo int-64 int-32 (hash/1 + hash/2 + 33) upper | |
to integer! hash/1 * 31 / upper | |
] | |
hash-v9: func [ | |
blob [binary!] | |
<local> out adder | |
][ | |
out: 1345345333 | |
adder: 7 | |
for-each byte blob [ | |
if not find [9 32] byte [ | |
out: me xor+ add (((out and+ 63) + adder) * byte) shift-32 out | |
adder: me + byte | |
] | |
] | |
int-64 out | |
] | |
crypt-v9: func [ | |
pass [binary!] | |
seed [binary!] | |
<local> | |
out upper hash pass-hash seed-hash | |
][ | |
upper: 33554431 ; to integer! #01FFFFFF | |
hash: reduce [ | |
hash-v9 pass | |
hash-v9 seed | |
] | |
hash: reduce [ | |
hash: modulo int-32 int-64 hash/1 xor+ hash/2 upper | |
to integer! hash / 2 | |
] | |
to text! to binary! out: collect [ | |
loop length of seed [ | |
keep add step hash upper 64 | |
] | |
] | |
] | |
hash-v10: func [ | |
blob [binary!] | |
<local> out adder | |
][ | |
out: reduce [1345345333 305419889] ; to integer! #12345671 | |
adder: 7 | |
for-each byte blob [ | |
; skip spaces and tabs | |
if not find [9 32] byte [ | |
out/1: me xor+ add (((63 and+ out/1) + adder) * byte) shift-32 out/1 | |
out/2: me + (out/1 xor+ shift-32 out/2) | |
adder: me + byte | |
] | |
] | |
; Remove sign bit (1<<31)-1) | |
out/1: me and+ 2147483647 ; to integer! #7FFFFFFF | |
out/2: me and+ 2147483647 | |
out | |
] | |
crypt-v10: func [ | |
pass [binary!] | |
seed [binary!] | |
<local> out upper hash mask | |
][ | |
upper: 1073741823 ; to integer! #3FFFFFFF | |
hash: reduce [ | |
hash-v10 pass | |
hash-v10 seed | |
] | |
hash: reduce [ | |
modulo hash/1/1 xor+ hash/2/1 upper | |
modulo hash/1/2 xor+ hash/2/2 upper | |
] | |
out: collect [ | |
loop length of seed [ | |
keep add step hash upper 64 | |
] | |
] | |
mask: step hash upper | |
for-next byte out [ | |
change byte byte/1 xor+ mask | |
] | |
to text! to binary! out | |
] | |
; --- New 4.1.0+ authentication scheme --- | |
crypt-v11: func [ | |
pass [binary!] | |
seed [binary!] | |
<local> key | |
][ | |
key: reduce [ | |
key: checksum/method pass 'sha1 | |
checksum/method key 'sha1 | |
] | |
key/1 xor+ checksum/method join-of seed key/2 'sha1 | |
] | |
; Version of Crypt v10 that possibly should work but doesn't | |
crypt-v10-bad: func [ | |
pass [binary!] | |
seed [binary!] | |
<local> | |
out upper hash mask step | |
][ | |
upper: 1073741823 ; to integer! #3FFFFFFF | |
hash: reduce [ | |
hash-v10 pass | |
hash-v10 seed | |
] | |
hash: reduce [ | |
modulo hash/1/1 xor+ hash/2/1 upper | |
modulo hash/1/2 xor+ hash/2/2 upper | |
] | |
step: does [ | |
hash/1: modulo (hash/1 * 3 + hash/2) upper | |
hash/2: modulo (hash/1 + hash/2 + 33) upper | |
to integer! hash/1 * 31 / upper | |
] | |
out: collect [ | |
loop length of seed [ | |
keep step + 64 | |
] | |
] | |
mask: step | |
for-next byte out [ | |
change byte byte/1 xor+ mask | |
] | |
to text! to binary! out | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment