github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/ext/hash/hash.go (about) 1 // Package hash provides cryptographic hash functions. 2 // 3 // Provided functions: 4 // - md4(data) 5 // - md5(data) 6 // - sha1(data) 7 // - sha3(data, size) (default size 256) 8 // - sha224(data) 9 // - sha256(data, size) (default size 256) 10 // - sha384(data) 11 // - sha512(data, size) (default size 512) 12 // - blake2s(data) 13 // - blake2b(data, size) (default size 512) 14 // - ripemd160(data) 15 // 16 // Each SQL function will only be registered if the corresponding 17 // [crypto.Hash] function is available. 18 // To ensure a specific hash function is available, 19 // import the implementing package. 20 package hash 21 22 import ( 23 "crypto" 24 25 "github.com/ncruces/go-sqlite3" 26 ) 27 28 // Register registers cryptographic hash functions for a database connection. 29 func Register(db *sqlite3.Conn) { 30 flags := sqlite3.DETERMINISTIC | sqlite3.INNOCUOUS 31 32 if crypto.MD4.Available() { 33 db.CreateFunction("md4", 1, flags, md4Func) 34 } 35 if crypto.MD5.Available() { 36 db.CreateFunction("md5", 1, flags, md5Func) 37 } 38 if crypto.SHA1.Available() { 39 db.CreateFunction("sha1", 1, flags, sha1Func) 40 } 41 if crypto.SHA3_512.Available() { 42 db.CreateFunction("sha3", 1, flags, sha3Func) 43 db.CreateFunction("sha3", 2, flags, sha3Func) 44 } 45 if crypto.SHA256.Available() { 46 db.CreateFunction("sha224", 1, flags, sha224Func) 47 db.CreateFunction("sha256", 1, flags, sha256Func) 48 db.CreateFunction("sha256", 2, flags, sha256Func) 49 } 50 if crypto.SHA512.Available() { 51 db.CreateFunction("sha384", 1, flags, sha384Func) 52 db.CreateFunction("sha512", 1, flags, sha512Func) 53 db.CreateFunction("sha512", 2, flags, sha512Func) 54 } 55 if crypto.BLAKE2s_256.Available() { 56 db.CreateFunction("blake2s", 1, flags, blake2sFunc) 57 } 58 if crypto.BLAKE2b_512.Available() { 59 db.CreateFunction("blake2b", 1, flags, blake2bFunc) 60 db.CreateFunction("blake2b", 2, flags, blake2bFunc) 61 } 62 if crypto.RIPEMD160.Available() { 63 db.CreateFunction("ripemd160", 1, flags, ripemd160Func) 64 } 65 } 66 67 func md4Func(ctx sqlite3.Context, arg ...sqlite3.Value) { 68 hashFunc(ctx, arg[0], crypto.MD4) 69 } 70 71 func md5Func(ctx sqlite3.Context, arg ...sqlite3.Value) { 72 hashFunc(ctx, arg[0], crypto.MD5) 73 } 74 75 func sha1Func(ctx sqlite3.Context, arg ...sqlite3.Value) { 76 hashFunc(ctx, arg[0], crypto.SHA1) 77 } 78 79 func ripemd160Func(ctx sqlite3.Context, arg ...sqlite3.Value) { 80 hashFunc(ctx, arg[0], crypto.RIPEMD160) 81 } 82 83 func hashFunc(ctx sqlite3.Context, arg sqlite3.Value, fn crypto.Hash) { 84 var data []byte 85 switch arg.Type() { 86 case sqlite3.NULL: 87 return 88 case sqlite3.BLOB: 89 data = arg.RawBlob() 90 default: 91 data = arg.RawText() 92 } 93 94 h := fn.New() 95 h.Write(data) 96 ctx.ResultBlob(h.Sum(nil)) 97 }