| ... | ... | @@ -8,7 +8,6 @@ const std = @import("std"); |
| 8 | 8 | const blake2 = crypto.hash.blake2; |
| 9 | 9 | const crypto = std.crypto; |
| 10 | 10 | const Io = std.Io; |
| 11 | | const math = std.math; |
| 12 | 11 | const mem = std.mem; |
| 13 | 12 | const phc_format = pwhash.phc_format; |
| 14 | 13 | const pwhash = crypto.pwhash; |
| ... | ... | @@ -322,7 +321,11 @@ fn processSegment( |
| 322 | 321 | random = blocks.items[prev][0]; |
| 323 | 322 | } |
| 324 | 323 | const new_offset = indexAlpha(random, lanes, segments, threads, n, slice, lane, index); |
| 325 | | processBlockXor(&blocks.items[offset], &blocks.items[prev], &blocks.items[new_offset]); |
| 324 | if (n == 0) { |
| 325 | processBlock(&blocks.items[offset], &blocks.items[prev], &blocks.items[new_offset]); |
| 326 | } else { |
| 327 | processBlockXor(&blocks.items[offset], &blocks.items[prev], &blocks.items[new_offset]); |
| 328 | } |
| 326 | 329 | } |
| 327 | 330 | } |
| 328 | 331 | |
| ... | ... | @@ -354,22 +357,25 @@ fn processBlockGeneric( |
| 354 | 357 | } |
| 355 | 358 | var i: usize = 0; |
| 356 | 359 | while (i < block_length) : (i += 16) { |
| 357 | | blamkaGeneric(t[i..][0..16]); |
| 360 | blamkaGeneric(.{ |
| 361 | &t[i + 0], &t[i + 1], &t[i + 2], &t[i + 3], |
| 362 | &t[i + 4], &t[i + 5], &t[i + 6], &t[i + 7], |
| 363 | &t[i + 8], &t[i + 9], &t[i + 10], &t[i + 11], |
| 364 | &t[i + 12], &t[i + 13], &t[i + 14], &t[i + 15], |
| 365 | }); |
| 358 | 366 | } |
| 359 | 367 | i = 0; |
| 360 | | var buffer: [16]u64 = undefined; |
| 361 | 368 | while (i < block_length / 8) : (i += 2) { |
| 362 | | var j: usize = 0; |
| 363 | | while (j < block_length / 8) : (j += 2) { |
| 364 | | buffer[j] = t[j * 8 + i]; |
| 365 | | buffer[j + 1] = t[j * 8 + i + 1]; |
| 366 | | } |
| 367 | | blamkaGeneric(&buffer); |
| 368 | | j = 0; |
| 369 | | while (j < block_length / 8) : (j += 2) { |
| 370 | | t[j * 8 + i] = buffer[j]; |
| 371 | | t[j * 8 + i + 1] = buffer[j + 1]; |
| 372 | | } |
| 369 | blamkaGeneric(.{ |
| 370 | &t[0 * 16 + i], &t[0 * 16 + i + 1], |
| 371 | &t[1 * 16 + i], &t[1 * 16 + i + 1], |
| 372 | &t[2 * 16 + i], &t[2 * 16 + i + 1], |
| 373 | &t[3 * 16 + i], &t[3 * 16 + i + 1], |
| 374 | &t[4 * 16 + i], &t[4 * 16 + i + 1], |
| 375 | &t[5 * 16 + i], &t[5 * 16 + i + 1], |
| 376 | &t[6 * 16 + i], &t[6 * 16 + i + 1], |
| 377 | &t[7 * 16 + i], &t[7 * 16 + i + 1], |
| 378 | }); |
| 373 | 379 | } |
| 374 | 380 | if (xor) { |
| 375 | 381 | for (t, 0..) |v, j| { |
| ... | ... | @@ -382,38 +388,50 @@ fn processBlockGeneric( |
| 382 | 388 | } |
| 383 | 389 | } |
| 384 | 390 | |
| 385 | | const QuarterRound = struct { a: usize, b: usize, c: usize, d: usize }; |
| 391 | const BlamkaVector = @Vector(4, u64); |
| 386 | 392 | |
| 387 | | fn Rp(a: usize, b: usize, c: usize, d: usize) QuarterRound { |
| 388 | | return .{ .a = a, .b = b, .c = c, .d = d }; |
| 393 | inline fn fBlaMka(x: BlamkaVector, y: BlamkaVector) BlamkaVector { |
| 394 | const x_lo: @Vector(4, u32) = @truncate(x); |
| 395 | const y_lo: @Vector(4, u32) = @truncate(y); |
| 396 | const xy = @as(BlamkaVector, x_lo) * @as(BlamkaVector, y_lo); |
| 397 | return x +% y +% @as(BlamkaVector, @splat(2)) *% xy; |
| 389 | 398 | } |
| 390 | 399 | |
| 391 | | fn fBlaMka(x: u64, y: u64) u64 { |
| 392 | | const xy = @as(u64, @as(u32, @truncate(x))) * @as(u64, @as(u32, @truncate(y))); |
| 393 | | return x +% y +% 2 *% xy; |
| 400 | inline fn rotrVector(x: BlamkaVector, comptime n: comptime_int) BlamkaVector { |
| 401 | return (x >> @splat(n)) | (x << @splat(64 - n)); |
| 394 | 402 | } |
| 395 | 403 | |
| 396 | | fn blamkaGeneric(x: *[16]u64) void { |
| 397 | | const rounds = comptime [_]QuarterRound{ |
| 398 | | Rp(0, 4, 8, 12), |
| 399 | | Rp(1, 5, 9, 13), |
| 400 | | Rp(2, 6, 10, 14), |
| 401 | | Rp(3, 7, 11, 15), |
| 402 | | Rp(0, 5, 10, 15), |
| 403 | | Rp(1, 6, 11, 12), |
| 404 | | Rp(2, 7, 8, 13), |
| 405 | | Rp(3, 4, 9, 14), |
| 406 | | }; |
| 407 | | inline for (rounds) |r| { |
| 408 | | x[r.a] = fBlaMka(x[r.a], x[r.b]); |
| 409 | | x[r.d] = math.rotr(u64, x[r.d] ^ x[r.a], 32); |
| 410 | | x[r.c] = fBlaMka(x[r.c], x[r.d]); |
| 411 | | x[r.b] = math.rotr(u64, x[r.b] ^ x[r.c], 24); |
| 412 | | x[r.a] = fBlaMka(x[r.a], x[r.b]); |
| 413 | | x[r.d] = math.rotr(u64, x[r.d] ^ x[r.a], 16); |
| 414 | | x[r.c] = fBlaMka(x[r.c], x[r.d]); |
| 415 | | x[r.b] = math.rotr(u64, x[r.b] ^ x[r.c], 63); |
| 416 | | } |
| 404 | inline fn blamkaRound(a: *BlamkaVector, b: *BlamkaVector, c: *BlamkaVector, d: *BlamkaVector) void { |
| 405 | a.* = fBlaMka(a.*, b.*); |
| 406 | d.* = rotrVector(d.* ^ a.*, 32); |
| 407 | c.* = fBlaMka(c.*, d.*); |
| 408 | b.* = rotrVector(b.* ^ c.*, 24); |
| 409 | a.* = fBlaMka(a.*, b.*); |
| 410 | d.* = rotrVector(d.* ^ a.*, 16); |
| 411 | c.* = fBlaMka(c.*, d.*); |
| 412 | b.* = rotrVector(b.* ^ c.*, 63); |
| 413 | } |
| 414 | |
| 415 | fn blamkaGeneric(xs: [16]*u64) void { |
| 416 | var a: BlamkaVector = .{ xs[0].*, xs[1].*, xs[2].*, xs[3].* }; |
| 417 | var b: BlamkaVector = .{ xs[4].*, xs[5].*, xs[6].*, xs[7].* }; |
| 418 | var c: BlamkaVector = .{ xs[8].*, xs[9].*, xs[10].*, xs[11].* }; |
| 419 | var d: BlamkaVector = .{ xs[12].*, xs[13].*, xs[14].*, xs[15].* }; |
| 420 | |
| 421 | blamkaRound(&a, &b, &c, &d); |
| 422 | |
| 423 | var b_diag = @shuffle(u64, b, undefined, [_]i32{ 1, 2, 3, 0 }); |
| 424 | var c_diag = @shuffle(u64, c, undefined, [_]i32{ 2, 3, 0, 1 }); |
| 425 | var d_diag = @shuffle(u64, d, undefined, [_]i32{ 3, 0, 1, 2 }); |
| 426 | blamkaRound(&a, &b_diag, &c_diag, &d_diag); |
| 427 | b = @shuffle(u64, b_diag, undefined, [_]i32{ 3, 0, 1, 2 }); |
| 428 | c = @shuffle(u64, c_diag, undefined, [_]i32{ 2, 3, 0, 1 }); |
| 429 | d = @shuffle(u64, d_diag, undefined, [_]i32{ 1, 2, 3, 0 }); |
| 430 | |
| 431 | inline for (0..4) |k| xs[k].* = a[k]; |
| 432 | inline for (0..4) |k| xs[4 + k].* = b[k]; |
| 433 | inline for (0..4) |k| xs[8 + k].* = c[k]; |
| 434 | inline for (0..4) |k| xs[12 + k].* = d[k]; |
| 417 | 435 | } |
| 418 | 436 | |
| 419 | 437 | fn finalize( |
| ... | ... | @@ -511,7 +529,7 @@ pub fn kdf( |
| 511 | 529 | var blocks = try Blocks.initCapacity(allocator, memory); |
| 512 | 530 | defer blocks.deinit(); |
| 513 | 531 | |
| 514 | | blocks.appendNTimesAssumeCapacity(@splat(0), memory); |
| 532 | _ = blocks.addManyAsSliceAssumeCapacity(memory); |
| 515 | 533 | |
| 516 | 534 | initBlocks(&blocks, &h0, memory, params.p); |
| 517 | 535 | try processBlocks(&blocks, params.t, memory, params.p, mode, io); |