libb2sでBLAKE2s
BLEKE2sはハッシュ化を行うアルゴリズムです。BLE通信を行う際にBLAKE2sで暗号化を行うことになったのでiOSでBLAKE2sを対応しているライブラリを探したのですが全然見つからず、最後に見つけたのがlibb2sでした。
現在はcarthageには対応していないようなのでcocoaPodでいれる必要がありそうです。
BLAKE2sで暗号化してみる
出力先を領域をあらかじめ確保しておく必要があります。
確保しておかない場合値を書き込む領域がそもそも存在しないのでエラーにはなりませんがnilの状態になります。
override func viewDidLoad() {
super.viewDidLoad()
//暗号化したいbyteデータ
let bytes: [Int8] = [49,50,51,52,53,54,55,56,57]
//出力されるメモリ領域をあらかじめ確保しておく必要がある
var outData = Data([1,1,1,1])
print("before:\(outData.hexEncodedString())")
let po = outData.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
return ptr
}
blake2s(po, bytes, nil, 4, bytes.count, 0)
print("after:\(outData.hexEncodedString())")
}
デバッグログ
コンソールを確認するとこんな感じでハッシュ化してくれていました。
before:01010101
after:6ade0c07
StringとDataのExtension
extension String {
func hexStringtoAscii() -> String {
let pattern = "(0x)?([0-9a-f]{2})"
let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let nsString = self as NSString
let range = NSRange(location: 0, length: nsString.length)
let matches = regex.matches(in: self, options: [], range: range)
let characters = matches.map {
Character(UnicodeScalar(UInt32(nsString.substring(with: $0.range(at: 2)), radix: 16)!)!)
}
return String(characters)
}
}
extension Data {
struct HexEncodingOptions: OptionSet {
let rawValue: Int
static let upperCase = HexEncodingOptions(rawValue: 1 << 0)
}
func hexEncodedString(options: HexEncodingOptions = []) -> String {
let format = options.contains(.upperCase) ? "%02hhX" : "%02hhx"
return map { String(format: format, $0) }.joined()
}
}
※2019/4/25日追記
Swift5でポインタ周りが少し変わったようです。ポインタがクロージャを抜けると解放されるようになった為、下記のようにblake2sを行う場所をクロージャ内に移さないと正しくhash化されなくなりました。
let outData = Data([1,1,1,1])
print("before:\(outData.hexEncodedString())")
var data = outData
_ = data.withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
blake2s(ptr, bytes, nil, 4, bytes.count, 0)
return ptr
}
print("after:\(data.hexEncodedString())")