| author | |
| committer | |
| log | 21106b9c9f9287a7f4477ac9a0b1b8ad04e245c3 |
| tree | 3aff693b14dc10730329168ad65a85b04eaed730 |
| parent | 9cfcd0c29677e11f76846b006757ff49e05e3d6f |
| parent | 3edace34d38c95673e56930ccfee1d16d0003359 |
| signature |
Breaking: sort std/crypto functions into categories19 files changed, 492 insertions(+), 411 deletions(-)
lib/std/bloom_filter.zig+1-1| ... | ... | @@ -158,7 +158,7 @@ pub fn BloomFilter( |
| 158 | 158 | } |
| 159 | 159 | |
| 160 | 160 | fn hashFunc(out: []u8, Ki: usize, in: []const u8) void { |
| 161 | var st = std.crypto.gimli.Hash.init(); | |
| 161 | var st = std.crypto.hash.Gimli.init(.{}); | |
| 162 | 162 | st.update(std.mem.asBytes(&Ki)); |
| 163 | 163 | st.update(in); |
| 164 | 164 | st.final(out); |
lib/std/build/write_file.zig+1-1| ... | ... | @@ -58,7 +58,7 @@ pub const WriteFileStep = struct { |
| 58 | 58 | // TODO port the cache system from stage1 to zig std lib. Until then we use blake2b |
| 59 | 59 | // directly and construct the path, and no "cache hit" detection happens; the files |
| 60 | 60 | // are always written. |
| 61 | var hash = std.crypto.Blake2b384.init(); | |
| 61 | var hash = std.crypto.hash.blake2.Blake2b384.init(); | |
| 62 | 62 | |
| 63 | 63 | // Random bytes to make WriteFileStep unique. Refresh this with |
| 64 | 64 | // new random bytes when WriteFileStep implementation is modified |
lib/std/cache_hash.zig+6-6| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | 6 | const std = @import("std.zig"); |
| 7 | const Blake3 = std.crypto.Blake3; | |
| 7 | const Blake3 = std.crypto.hash.Blake3; | |
| 8 | 8 | const fs = std.fs; |
| 9 | 9 | const base64 = std.base64; |
| 10 | 10 | const ArrayList = std.ArrayList; |
| ... | ... | @@ -56,7 +56,7 @@ pub const CacheHash = struct { |
| 56 | 56 | pub fn init(allocator: *Allocator, dir: fs.Dir, manifest_dir_path: []const u8) !CacheHash { |
| 57 | 57 | return CacheHash{ |
| 58 | 58 | .allocator = allocator, |
| 59 | .blake3 = Blake3.init(), | |
| 59 | .blake3 = Blake3.init(.{}), | |
| 60 | 60 | .manifest_dir = try dir.makeOpenPath(manifest_dir_path, .{}), |
| 61 | 61 | .manifest_file = null, |
| 62 | 62 | .manifest_dirty = false, |
| ... | ... | @@ -137,7 +137,7 @@ pub const CacheHash = struct { |
| 137 | 137 | |
| 138 | 138 | base64_encoder.encode(self.b64_digest[0..], &bin_digest); |
| 139 | 139 | |
| 140 | self.blake3 = Blake3.init(); | |
| 140 | self.blake3 = Blake3.init(.{}); | |
| 141 | 141 | self.blake3.update(&bin_digest); |
| 142 | 142 | |
| 143 | 143 | const manifest_file_path = try fmt.allocPrint(self.allocator, "{}.txt", .{self.b64_digest}); |
| ... | ... | @@ -256,7 +256,7 @@ pub const CacheHash = struct { |
| 256 | 256 | // cache miss |
| 257 | 257 | // keep the manifest file open |
| 258 | 258 | // reset the hash |
| 259 | self.blake3 = Blake3.init(); | |
| 259 | self.blake3 = Blake3.init(.{}); | |
| 260 | 260 | self.blake3.update(&bin_digest); |
| 261 | 261 | |
| 262 | 262 | // Remove files not in the initial hash |
| ... | ... | @@ -304,7 +304,7 @@ pub const CacheHash = struct { |
| 304 | 304 | |
| 305 | 305 | // Hash while reading from disk, to keep the contents in the cpu cache while |
| 306 | 306 | // doing hashing. |
| 307 | var blake3 = Blake3.init(); | |
| 307 | var blake3 = Blake3.init(.{}); | |
| 308 | 308 | var off: usize = 0; |
| 309 | 309 | while (true) { |
| 310 | 310 | // give me everything you've got, captain |
| ... | ... | @@ -434,7 +434,7 @@ pub const CacheHash = struct { |
| 434 | 434 | }; |
| 435 | 435 | |
| 436 | 436 | fn hashFile(file: fs.File, bin_digest: []u8) !void { |
| 437 | var blake3 = Blake3.init(); | |
| 437 | var blake3 = Blake3.init(.{}); | |
| 438 | 438 | var buf: [1024]u8 = undefined; |
| 439 | 439 | |
| 440 | 440 | while (true) { |
lib/std/crypto.zig+68-55| ... | ... | @@ -3,58 +3,66 @@ |
| 3 | 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | pub const Md5 = @import("crypto/md5.zig").Md5; | |
| 7 | pub const Sha1 = @import("crypto/sha1.zig").Sha1; | |
| 8 | 6 | |
| 9 | const sha2 = @import("crypto/sha2.zig"); | |
| 10 | pub const Sha224 = sha2.Sha224; | |
| 11 | pub const Sha256 = sha2.Sha256; | |
| 12 | pub const Sha384 = sha2.Sha384; | |
| 13 | pub const Sha512 = sha2.Sha512; | |
| 14 | ||
| 15 | const sha3 = @import("crypto/sha3.zig"); | |
| 16 | pub const Sha3_224 = sha3.Sha3_224; | |
| 17 | pub const Sha3_256 = sha3.Sha3_256; | |
| 18 | pub const Sha3_384 = sha3.Sha3_384; | |
| 19 | pub const Sha3_512 = sha3.Sha3_512; | |
| 7 | /// Hash functions. | |
| 8 | pub const hash = struct { | |
| 9 | pub const Md5 = @import("crypto/md5.zig").Md5; | |
| 10 | pub const Sha1 = @import("crypto/sha1.zig").Sha1; | |
| 11 | pub const sha2 = @import("crypto/sha2.zig"); | |
| 12 | pub const sha3 = @import("crypto/sha3.zig"); | |
| 13 | pub const blake2 = @import("crypto/blake2.zig"); | |
| 14 | pub const Blake3 = @import("crypto/blake3.zig").Blake3; | |
| 15 | pub const Gimli = @import("crypto/gimli.zig").Hash; | |
| 16 | }; | |
| 20 | 17 | |
| 21 | pub const gimli = @import("crypto/gimli.zig"); | |
| 18 | /// Authentication (MAC) functions. | |
| 19 | pub const auth = struct { | |
| 20 | pub const hmac = @import("crypto/hmac.zig"); | |
| 21 | }; | |
| 22 | 22 | |
| 23 | const blake2 = @import("crypto/blake2.zig"); | |
| 24 | pub const Blake2s224 = blake2.Blake2s224; | |
| 25 | pub const Blake2s256 = blake2.Blake2s256; | |
| 26 | pub const Blake2b384 = blake2.Blake2b384; | |
| 27 | pub const Blake2b512 = blake2.Blake2b512; | |
| 23 | /// Authenticated Encryption with Associated Data | |
| 24 | pub const aead = struct { | |
| 25 | const chacha20 = @import("crypto/chacha20.zig"); | |
| 28 | 26 | |
| 29 | pub const Blake3 = @import("crypto/blake3.zig").Blake3; | |
| 27 | pub const Gimli = @import("crypto/gimli.zig").Aead; | |
| 28 | pub const ChaCha20Poly1305 = chacha20.Chacha20Poly1305; | |
| 29 | pub const XChaCha20Poly1305 = chacha20.XChacha20Poly1305; | |
| 30 | }; | |
| 30 | 31 | |
| 31 | const hmac = @import("crypto/hmac.zig"); | |
| 32 | pub const HmacMd5 = hmac.HmacMd5; | |
| 33 | pub const HmacSha1 = hmac.HmacSha1; | |
| 34 | pub const HmacSha256 = hmac.HmacSha256; | |
| 35 | pub const HmacBlake2s256 = hmac.HmacBlake2s256; | |
| 32 | /// MAC functions requiring single-use secret keys. | |
| 33 | pub const onetimeauth = struct { | |
| 34 | pub const Poly1305 = @import("crypto/poly1305.zig").Poly1305; | |
| 35 | }; | |
| 36 | 36 | |
| 37 | pub const chacha20 = @import("crypto/chacha20.zig"); | |
| 38 | pub const chaCha20IETF = chacha20.chaCha20IETF; | |
| 39 | pub const chaCha20With64BitNonce = chacha20.chaCha20With64BitNonce; | |
| 40 | pub const xChaCha20IETF = chacha20.xChaCha20IETF; | |
| 37 | /// Core functions, that should rarely be used directly by applications. | |
| 38 | pub const core = struct { | |
| 39 | pub const aes = @import("crypto/aes.zig"); | |
| 40 | pub const Gimli = @import("crypto/gimli.zig").State; | |
| 41 | }; | |
| 41 | 42 | |
| 42 | pub const Poly1305 = @import("crypto/poly1305.zig").Poly1305; | |
| 43 | /// Elliptic-curve arithmetic. | |
| 44 | pub const ecc = struct { | |
| 45 | pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519; | |
| 46 | pub const Edwards25519 = @import("crypto/25519/edwards25519.zig").Edwards25519; | |
| 47 | pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255; | |
| 48 | }; | |
| 43 | 49 | |
| 44 | const import_aes = @import("crypto/aes.zig"); | |
| 45 | pub const AES128 = import_aes.AES128; | |
| 46 | pub const AES256 = import_aes.AES256; | |
| 50 | /// Diffie-Hellman key exchange functions. | |
| 51 | pub const dh = struct { | |
| 52 | pub const X25519 = @import("crypto/25519/x25519.zig").X25519; | |
| 53 | }; | |
| 47 | 54 | |
| 48 | pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519; | |
| 49 | pub const Ed25519 = @import("crypto/25519/ed25519.zig").Ed25519; | |
| 50 | pub const Edwards25519 = @import("crypto/25519/edwards25519.zig").Edwards25519; | |
| 51 | pub const X25519 = @import("crypto/25519/x25519.zig").X25519; | |
| 52 | pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255; | |
| 55 | /// Digital signature functions. | |
| 56 | pub const sign = struct { | |
| 57 | pub const Ed25519 = @import("crypto/25519/ed25519.zig").Ed25519; | |
| 58 | }; | |
| 53 | 59 | |
| 54 | pub const aead = struct { | |
| 55 | pub const Gimli = gimli.Aead; | |
| 56 | pub const ChaCha20Poly1305 = chacha20.Chacha20Poly1305; | |
| 57 | pub const XChaCha20Poly1305 = chacha20.XChacha20Poly1305; | |
| 60 | /// Stream ciphers. These do not provide any kind of authentication. | |
| 61 | /// Most applications should be using AEAD constructions instead of stream ciphers directly. | |
| 62 | pub const stream = struct { | |
| 63 | pub const ChaCha20IETF = @import("crypto/chacha20.zig").ChaCha20IETF; | |
| 64 | pub const XChaCha20IETF = @import("crypto/chacha20.zig").XChaCha20IETF; | |
| 65 | pub const ChaCha20With64BitNonce = @import("crypto/chacha20.zig").ChaCha20With64BitNonce; | |
| 58 | 66 | }; |
| 59 | 67 | |
| 60 | 68 | const std = @import("std.zig"); |
| ... | ... | @@ -83,27 +91,32 @@ test "crypto" { |
| 83 | 91 | |
| 84 | 92 | test "issue #4532: no index out of bounds" { |
| 85 | 93 | const types = [_]type{ |
| 86 | Md5, | |
| 87 | Sha1, | |
| 88 | Sha224, | |
| 89 | Sha256, | |
| 90 | Sha384, | |
| 91 | Sha512, | |
| 92 | Blake2s224, | |
| 93 | Blake2s256, | |
| 94 | Blake2b384, | |
| 95 | Blake2b512, | |
| 94 | hash.Md5, | |
| 95 | hash.Sha1, | |
| 96 | hash.sha2.Sha224, | |
| 97 | hash.sha2.Sha256, | |
| 98 | hash.sha2.Sha384, | |
| 99 | hash.sha2.Sha512, | |
| 100 | hash.sha3.Sha3_224, | |
| 101 | hash.sha3.Sha3_256, | |
| 102 | hash.sha3.Sha3_384, | |
| 103 | hash.sha3.Sha3_512, | |
| 104 | hash.blake2.Blake2s224, | |
| 105 | hash.blake2.Blake2s256, | |
| 106 | hash.blake2.Blake2b384, | |
| 107 | hash.blake2.Blake2b512, | |
| 108 | hash.Gimli, | |
| 96 | 109 | }; |
| 97 | 110 | |
| 98 | 111 | inline for (types) |Hasher| { |
| 99 | 112 | var block = [_]u8{'#'} ** Hasher.block_length; |
| 100 | 113 | var out1: [Hasher.digest_length]u8 = undefined; |
| 101 | 114 | var out2: [Hasher.digest_length]u8 = undefined; |
| 102 | ||
| 103 | var h = Hasher.init(); | |
| 115 | const h0 = Hasher.init(.{}); | |
| 116 | var h = h0; | |
| 104 | 117 | h.update(block[0..]); |
| 105 | 118 | h.final(out1[0..]); |
| 106 | h.reset(); | |
| 119 | h = h0; | |
| 107 | 120 | h.update(block[0..1]); |
| 108 | 121 | h.update(block[1..]); |
| 109 | 122 | h.final(out2[0..]); |
lib/std/crypto/25519/ed25519.zig+6-6| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | const std = @import("std"); |
| 7 | 7 | const fmt = std.fmt; |
| 8 | 8 | const mem = std.mem; |
| 9 | const Sha512 = std.crypto.Sha512; | |
| 9 | const Sha512 = std.crypto.hash.sha2.Sha512; | |
| 10 | 10 | |
| 11 | 11 | /// Ed25519 (EdDSA) signatures. |
| 12 | 12 | pub const Ed25519 = struct { |
| ... | ... | @@ -33,7 +33,7 @@ pub const Ed25519 = struct { |
| 33 | 33 | /// from which the actual secret is derived. |
| 34 | 34 | pub fn createKeyPair(seed: [seed_length]u8) ![keypair_length]u8 { |
| 35 | 35 | var az: [Sha512.digest_length]u8 = undefined; |
| 36 | var h = Sha512.init(); | |
| 36 | var h = Sha512.init(.{}); | |
| 37 | 37 | h.update(&seed); |
| 38 | 38 | h.final(&az); |
| 39 | 39 | const p = try Curve.basePoint.clampedMul(az[0..32].*); |
| ... | ... | @@ -56,11 +56,11 @@ pub const Ed25519 = struct { |
| 56 | 56 | pub fn sign(msg: []const u8, key_pair: [keypair_length]u8, noise: ?[noise_length]u8) ![signature_length]u8 { |
| 57 | 57 | const public_key = key_pair[32..]; |
| 58 | 58 | var az: [Sha512.digest_length]u8 = undefined; |
| 59 | var h = Sha512.init(); | |
| 59 | var h = Sha512.init(.{}); | |
| 60 | 60 | h.update(key_pair[0..seed_length]); |
| 61 | 61 | h.final(&az); |
| 62 | 62 | |
| 63 | h = Sha512.init(); | |
| 63 | h = Sha512.init(.{}); | |
| 64 | 64 | if (noise) |*z| { |
| 65 | 65 | h.update(z); |
| 66 | 66 | } |
| ... | ... | @@ -74,7 +74,7 @@ pub const Ed25519 = struct { |
| 74 | 74 | var sig: [signature_length]u8 = undefined; |
| 75 | 75 | mem.copy(u8, sig[0..32], &r.toBytes()); |
| 76 | 76 | mem.copy(u8, sig[32..], public_key); |
| 77 | h = Sha512.init(); | |
| 77 | h = Sha512.init(.{}); | |
| 78 | 78 | h.update(&sig); |
| 79 | 79 | h.update(msg); |
| 80 | 80 | var hram64: [Sha512.digest_length]u8 = undefined; |
| ... | ... | @@ -98,7 +98,7 @@ pub const Ed25519 = struct { |
| 98 | 98 | const a = try Curve.fromBytes(public_key); |
| 99 | 99 | try a.rejectIdentity(); |
| 100 | 100 | |
| 101 | var h = Sha512.init(); | |
| 101 | var h = Sha512.init(.{}); | |
| 102 | 102 | h.update(r); |
| 103 | 103 | h.update(&public_key); |
| 104 | 104 | h.update(msg); |
lib/std/crypto/benchmark.zig+20-19| ... | ... | @@ -22,20 +22,20 @@ const Crypto = struct { |
| 22 | 22 | }; |
| 23 | 23 | |
| 24 | 24 | const hashes = [_]Crypto{ |
| 25 | Crypto{ .ty = crypto.Md5, .name = "md5" }, | |
| 26 | Crypto{ .ty = crypto.Sha1, .name = "sha1" }, | |
| 27 | Crypto{ .ty = crypto.Sha256, .name = "sha256" }, | |
| 28 | Crypto{ .ty = crypto.Sha512, .name = "sha512" }, | |
| 29 | Crypto{ .ty = crypto.Sha3_256, .name = "sha3-256" }, | |
| 30 | Crypto{ .ty = crypto.Sha3_512, .name = "sha3-512" }, | |
| 31 | Crypto{ .ty = crypto.gimli.Hash, .name = "gimli-hash" }, | |
| 32 | Crypto{ .ty = crypto.Blake2s256, .name = "blake2s" }, | |
| 33 | Crypto{ .ty = crypto.Blake2b512, .name = "blake2b" }, | |
| 34 | Crypto{ .ty = crypto.Blake3, .name = "blake3" }, | |
| 25 | Crypto{ .ty = crypto.hash.Md5, .name = "md5" }, | |
| 26 | Crypto{ .ty = crypto.hash.Sha1, .name = "sha1" }, | |
| 27 | Crypto{ .ty = crypto.hash.sha2.Sha256, .name = "sha256" }, | |
| 28 | Crypto{ .ty = crypto.hash.sha2.Sha512, .name = "sha512" }, | |
| 29 | Crypto{ .ty = crypto.hash.sha3.Sha3_256, .name = "sha3-256" }, | |
| 30 | Crypto{ .ty = crypto.hash.sha3.Sha3_512, .name = "sha3-512" }, | |
| 31 | Crypto{ .ty = crypto.hash.Gimli, .name = "gimli-hash" }, | |
| 32 | Crypto{ .ty = crypto.hash.blake2.Blake2s256, .name = "blake2s" }, | |
| 33 | Crypto{ .ty = crypto.hash.blake2.Blake2b512, .name = "blake2b" }, | |
| 34 | Crypto{ .ty = crypto.hash.Blake3, .name = "blake3" }, | |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | 37 | pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 { |
| 38 | var h = Hash.init(); | |
| 38 | var h = Hash.init(.{}); | |
| 39 | 39 | |
| 40 | 40 | var block: [Hash.digest_length]u8 = undefined; |
| 41 | 41 | prng.random.bytes(block[0..]); |
| ... | ... | @@ -55,19 +55,20 @@ pub fn benchmarkHash(comptime Hash: anytype, comptime bytes: comptime_int) !u64 |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | const macs = [_]Crypto{ |
| 58 | Crypto{ .ty = crypto.Poly1305, .name = "poly1305" }, | |
| 59 | Crypto{ .ty = crypto.HmacMd5, .name = "hmac-md5" }, | |
| 60 | Crypto{ .ty = crypto.HmacSha1, .name = "hmac-sha1" }, | |
| 61 | Crypto{ .ty = crypto.HmacSha256, .name = "hmac-sha256" }, | |
| 58 | Crypto{ .ty = crypto.onetimeauth.Poly1305, .name = "poly1305" }, | |
| 59 | Crypto{ .ty = crypto.auth.hmac.HmacMd5, .name = "hmac-md5" }, | |
| 60 | Crypto{ .ty = crypto.auth.hmac.HmacSha1, .name = "hmac-sha1" }, | |
| 61 | Crypto{ .ty = crypto.auth.hmac.sha2.HmacSha256, .name = "hmac-sha256" }, | |
| 62 | Crypto{ .ty = crypto.auth.hmac.sha2.HmacSha512, .name = "hmac-sha512" }, | |
| 62 | 63 | }; |
| 63 | 64 | |
| 64 | 65 | pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { |
| 65 | std.debug.assert(32 >= Mac.mac_length and 32 >= Mac.minimum_key_length); | |
| 66 | std.debug.assert(64 >= Mac.mac_length and 32 >= Mac.minimum_key_length); | |
| 66 | 67 | |
| 67 | 68 | var in: [1 * MiB]u8 = undefined; |
| 68 | 69 | prng.random.bytes(in[0..]); |
| 69 | 70 | |
| 70 | var key: [32]u8 = undefined; | |
| 71 | var key: [64]u8 = undefined; | |
| 71 | 72 | prng.random.bytes(key[0..]); |
| 72 | 73 | |
| 73 | 74 | var offset: usize = 0; |
| ... | ... | @@ -84,7 +85,7 @@ pub fn benchmarkMac(comptime Mac: anytype, comptime bytes: comptime_int) !u64 { |
| 84 | 85 | return throughput; |
| 85 | 86 | } |
| 86 | 87 | |
| 87 | const exchanges = [_]Crypto{Crypto{ .ty = crypto.X25519, .name = "x25519" }}; | |
| 88 | const exchanges = [_]Crypto{Crypto{ .ty = crypto.dh.X25519, .name = "x25519" }}; | |
| 88 | 89 | |
| 89 | 90 | pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_count: comptime_int) !u64 { |
| 90 | 91 | std.debug.assert(DhKeyExchange.minimum_key_length >= DhKeyExchange.secret_length); |
| ... | ... | @@ -111,7 +112,7 @@ pub fn benchmarkKeyExchange(comptime DhKeyExchange: anytype, comptime exchange_c |
| 111 | 112 | return throughput; |
| 112 | 113 | } |
| 113 | 114 | |
| 114 | const signatures = [_]Crypto{Crypto{ .ty = crypto.Ed25519, .name = "ed25519" }}; | |
| 115 | const signatures = [_]Crypto{Crypto{ .ty = crypto.sign.Ed25519, .name = "ed25519" }}; | |
| 115 | 116 | |
| 116 | 117 | pub fn benchmarkSignatures(comptime Signature: anytype, comptime signatures_count: comptime_int) !u64 { |
| 117 | 118 | var seed: [Signature.seed_length]u8 = undefined; |
lib/std/crypto/blake2.zig+102-78| ... | ... | @@ -40,6 +40,7 @@ pub fn Blake2s(comptime out_len: usize) type { |
| 40 | 40 | const Self = @This(); |
| 41 | 41 | pub const block_length = 64; |
| 42 | 42 | pub const digest_length = out_len / 8; |
| 43 | pub const Options = struct { key: ?[]const u8 = null, salt: ?[8]u8 = null, context: ?[8]u8 = null }; | |
| 43 | 44 | |
| 44 | 45 | const iv = [8]u32{ |
| 45 | 46 | 0x6A09E667, |
| ... | ... | @@ -71,42 +72,36 @@ pub fn Blake2s(comptime out_len: usize) type { |
| 71 | 72 | buf: [64]u8, |
| 72 | 73 | buf_len: u8, |
| 73 | 74 | |
| 74 | key: []const u8, | |
| 75 | ||
| 76 | pub fn init() Self { | |
| 77 | return init_keyed(""); | |
| 78 | } | |
| 79 | ||
| 80 | pub fn init_keyed(key: []const u8) Self { | |
| 75 | pub fn init(options: Options) Self { | |
| 81 | 76 | debug.assert(8 <= out_len and out_len <= 512); |
| 82 | 77 | |
| 83 | var s: Self = undefined; | |
| 84 | s.key = key; | |
| 85 | s.reset(); | |
| 86 | return s; | |
| 87 | } | |
| 88 | ||
| 89 | pub fn reset(d: *Self) void { | |
| 78 | var d: Self = undefined; | |
| 90 | 79 | mem.copy(u32, d.h[0..], iv[0..]); |
| 91 | 80 | |
| 81 | const key_len = if (options.key) |key| key.len else 0; | |
| 92 | 82 | // default parameters |
| 93 | d.h[0] ^= 0x01010000 ^ @truncate(u32, d.key.len << 8) ^ @intCast(u32, out_len >> 3); | |
| 83 | d.h[0] ^= 0x01010000 ^ @truncate(u32, key_len << 8) ^ @intCast(u32, out_len >> 3); | |
| 94 | 84 | d.t = 0; |
| 95 | 85 | d.buf_len = 0; |
| 96 | 86 | |
| 97 | if (d.key.len > 0) { | |
| 98 | mem.set(u8, d.buf[d.key.len..], 0); | |
| 99 | d.update(d.key); | |
| 87 | if (options.salt) |salt| { | |
| 88 | d.h[4] ^= mem.readIntLittle(u32, salt[0..4]); | |
| 89 | d.h[5] ^= mem.readIntLittle(u32, salt[4..8]); | |
| 90 | } | |
| 91 | if (options.context) |context| { | |
| 92 | d.h[6] ^= mem.readIntLittle(u32, context[0..4]); | |
| 93 | d.h[7] ^= mem.readIntLittle(u32, context[4..8]); | |
| 94 | } | |
| 95 | if (key_len > 0) { | |
| 96 | mem.set(u8, d.buf[key_len..], 0); | |
| 97 | d.update(options.key.?); | |
| 100 | 98 | d.buf_len = 64; |
| 101 | 99 | } |
| 100 | return d; | |
| 102 | 101 | } |
| 103 | 102 | |
| 104 | pub fn hash(b: []const u8, out: []u8) void { | |
| 105 | Self.hash_keyed("", b, out); | |
| 106 | } | |
| 107 | ||
| 108 | pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void { | |
| 109 | var d = Self.init_keyed(key); | |
| 103 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 104 | var d = Self.init(options); | |
| 110 | 105 | d.update(b); |
| 111 | 106 | d.final(out); |
| 112 | 107 | } |
| ... | ... | @@ -215,7 +210,7 @@ test "blake2s224 single" { |
| 215 | 210 | } |
| 216 | 211 | |
| 217 | 212 | test "blake2s224 streaming" { |
| 218 | var h = Blake2s224.init(); | |
| 213 | var h = Blake2s224.init(.{}); | |
| 219 | 214 | var out: [28]u8 = undefined; |
| 220 | 215 | |
| 221 | 216 | const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4"; |
| ... | ... | @@ -225,12 +220,12 @@ test "blake2s224 streaming" { |
| 225 | 220 | |
| 226 | 221 | const h2 = "0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55"; |
| 227 | 222 | |
| 228 | h.reset(); | |
| 223 | h = Blake2s224.init(.{}); | |
| 229 | 224 | h.update("abc"); |
| 230 | 225 | h.final(out[0..]); |
| 231 | 226 | htest.assertEqual(h2, out[0..]); |
| 232 | 227 | |
| 233 | h.reset(); | |
| 228 | h = Blake2s224.init(.{}); | |
| 234 | 229 | h.update("a"); |
| 235 | 230 | h.update("b"); |
| 236 | 231 | h.update("c"); |
| ... | ... | @@ -239,16 +234,29 @@ test "blake2s224 streaming" { |
| 239 | 234 | |
| 240 | 235 | const h3 = "557381a78facd2b298640f4e32113e58967d61420af1aa939d0cfe01"; |
| 241 | 236 | |
| 242 | h.reset(); | |
| 237 | h = Blake2s224.init(.{}); | |
| 243 | 238 | h.update("a" ** 32); |
| 244 | 239 | h.update("b" ** 32); |
| 245 | 240 | h.final(out[0..]); |
| 246 | 241 | htest.assertEqual(h3, out[0..]); |
| 247 | 242 | |
| 248 | h.reset(); | |
| 243 | h = Blake2s224.init(.{}); | |
| 249 | 244 | h.update("a" ** 32 ++ "b" ** 32); |
| 250 | 245 | h.final(out[0..]); |
| 251 | 246 | htest.assertEqual(h3, out[0..]); |
| 247 | ||
| 248 | const h4 = "a4d6a9d253441b80e5dfd60a04db169ffab77aec56a2855c402828c3"; | |
| 249 | ||
| 250 | h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); | |
| 251 | h.update("a" ** 32); | |
| 252 | h.update("b" ** 32); | |
| 253 | h.final(out[0..]); | |
| 254 | htest.assertEqual(h4, out[0..]); | |
| 255 | ||
| 256 | h = Blake2s224.init(.{ .context = [_]u8{0x69} ** 8, .salt = [_]u8{0x42} ** 8 }); | |
| 257 | h.update("a" ** 32 ++ "b" ** 32); | |
| 258 | h.final(out[0..]); | |
| 259 | htest.assertEqual(h4, out[0..]); | |
| 252 | 260 | } |
| 253 | 261 | |
| 254 | 262 | test "comptime blake2s224" { |
| ... | ... | @@ -261,7 +269,7 @@ test "comptime blake2s224" { |
| 261 | 269 | |
| 262 | 270 | htest.assertEqualHash(Blake2s224, h1, block[0..]); |
| 263 | 271 | |
| 264 | var h = Blake2s224.init(); | |
| 272 | var h = Blake2s224.init(.{}); | |
| 265 | 273 | h.update(&block); |
| 266 | 274 | h.final(out[0..]); |
| 267 | 275 | |
| ... | ... | @@ -284,7 +292,7 @@ test "blake2s256 single" { |
| 284 | 292 | } |
| 285 | 293 | |
| 286 | 294 | test "blake2s256 streaming" { |
| 287 | var h = Blake2s256.init(); | |
| 295 | var h = Blake2s256.init(.{}); | |
| 288 | 296 | var out: [32]u8 = undefined; |
| 289 | 297 | |
| 290 | 298 | const h1 = "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"; |
| ... | ... | @@ -294,12 +302,12 @@ test "blake2s256 streaming" { |
| 294 | 302 | |
| 295 | 303 | const h2 = "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"; |
| 296 | 304 | |
| 297 | h.reset(); | |
| 305 | h = Blake2s256.init(.{}); | |
| 298 | 306 | h.update("abc"); |
| 299 | 307 | h.final(out[0..]); |
| 300 | 308 | htest.assertEqual(h2, out[0..]); |
| 301 | 309 | |
| 302 | h.reset(); | |
| 310 | h = Blake2s256.init(.{}); | |
| 303 | 311 | h.update("a"); |
| 304 | 312 | h.update("b"); |
| 305 | 313 | h.update("c"); |
| ... | ... | @@ -308,13 +316,13 @@ test "blake2s256 streaming" { |
| 308 | 316 | |
| 309 | 317 | const h3 = "8d8711dade07a6b92b9a3ea1f40bee9b2c53ff3edd2a273dec170b0163568977"; |
| 310 | 318 | |
| 311 | h.reset(); | |
| 319 | h = Blake2s256.init(.{}); | |
| 312 | 320 | h.update("a" ** 32); |
| 313 | 321 | h.update("b" ** 32); |
| 314 | 322 | h.final(out[0..]); |
| 315 | 323 | htest.assertEqual(h3, out[0..]); |
| 316 | 324 | |
| 317 | h.reset(); | |
| 325 | h = Blake2s256.init(.{}); | |
| 318 | 326 | h.update("a" ** 32 ++ "b" ** 32); |
| 319 | 327 | h.final(out[0..]); |
| 320 | 328 | htest.assertEqual(h3, out[0..]); |
| ... | ... | @@ -326,16 +334,16 @@ test "blake2s256 keyed" { |
| 326 | 334 | const h1 = "10f918da4d74fab3302e48a5d67d03804b1ec95372a62a0f33b7c9fa28ba1ae6"; |
| 327 | 335 | const key = "secret_key"; |
| 328 | 336 | |
| 329 | Blake2s256.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out); | |
| 337 | Blake2s256.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); | |
| 330 | 338 | htest.assertEqual(h1, out[0..]); |
| 331 | 339 | |
| 332 | var h = Blake2s256.init_keyed(key); | |
| 340 | var h = Blake2s256.init(.{ .key = key }); | |
| 333 | 341 | h.update("a" ** 64 ++ "b" ** 64); |
| 334 | 342 | h.final(out[0..]); |
| 335 | 343 | |
| 336 | 344 | htest.assertEqual(h1, out[0..]); |
| 337 | 345 | |
| 338 | h.reset(); | |
| 346 | h = Blake2s256.init(.{ .key = key }); | |
| 339 | 347 | h.update("a" ** 64); |
| 340 | 348 | h.update("b" ** 64); |
| 341 | 349 | h.final(out[0..]); |
| ... | ... | @@ -353,7 +361,7 @@ test "comptime blake2s256" { |
| 353 | 361 | |
| 354 | 362 | htest.assertEqualHash(Blake2s256, h1, block[0..]); |
| 355 | 363 | |
| 356 | var h = Blake2s256.init(); | |
| 364 | var h = Blake2s256.init(.{}); | |
| 357 | 365 | h.update(&block); |
| 358 | 366 | h.final(out[0..]); |
| 359 | 367 | |
| ... | ... | @@ -364,6 +372,7 @@ test "comptime blake2s256" { |
| 364 | 372 | ///////////////////// |
| 365 | 373 | // Blake2b |
| 366 | 374 | |
| 375 | pub const Blake2b256 = Blake2b(256); | |
| 367 | 376 | pub const Blake2b384 = Blake2b(384); |
| 368 | 377 | pub const Blake2b512 = Blake2b(512); |
| 369 | 378 | |
| ... | ... | @@ -372,6 +381,7 @@ pub fn Blake2b(comptime out_len: usize) type { |
| 372 | 381 | const Self = @This(); |
| 373 | 382 | pub const block_length = 128; |
| 374 | 383 | pub const digest_length = out_len / 8; |
| 384 | pub const Options = struct { key: ?[]const u8 = null, salt: ?[16]u8 = null, context: ?[16]u8 = null }; | |
| 375 | 385 | |
| 376 | 386 | const iv = [8]u64{ |
| 377 | 387 | 0x6a09e667f3bcc908, |
| ... | ... | @@ -405,42 +415,36 @@ pub fn Blake2b(comptime out_len: usize) type { |
| 405 | 415 | buf: [128]u8, |
| 406 | 416 | buf_len: u8, |
| 407 | 417 | |
| 408 | key: []const u8, | |
| 409 | ||
| 410 | pub fn init() Self { | |
| 411 | return init_keyed(""); | |
| 412 | } | |
| 413 | ||
| 414 | pub fn init_keyed(key: []const u8) Self { | |
| 418 | pub fn init(options: Options) Self { | |
| 415 | 419 | debug.assert(8 <= out_len and out_len <= 512); |
| 416 | 420 | |
| 417 | var s: Self = undefined; | |
| 418 | s.key = key; | |
| 419 | s.reset(); | |
| 420 | return s; | |
| 421 | } | |
| 422 | ||
| 423 | pub fn reset(d: *Self) void { | |
| 421 | var d: Self = undefined; | |
| 424 | 422 | mem.copy(u64, d.h[0..], iv[0..]); |
| 425 | 423 | |
| 424 | const key_len = if (options.key) |key| key.len else 0; | |
| 426 | 425 | // default parameters |
| 427 | d.h[0] ^= 0x01010000 ^ (d.key.len << 8) ^ (out_len >> 3); | |
| 426 | d.h[0] ^= 0x01010000 ^ (key_len << 8) ^ (out_len >> 3); | |
| 428 | 427 | d.t = 0; |
| 429 | 428 | d.buf_len = 0; |
| 430 | 429 | |
| 431 | if (d.key.len > 0) { | |
| 432 | mem.set(u8, d.buf[d.key.len..], 0); | |
| 433 | d.update(d.key); | |
| 430 | if (options.salt) |salt| { | |
| 431 | d.h[4] ^= mem.readIntLittle(u64, salt[0..8]); | |
| 432 | d.h[5] ^= mem.readIntLittle(u64, salt[8..16]); | |
| 433 | } | |
| 434 | if (options.context) |context| { | |
| 435 | d.h[6] ^= mem.readIntLittle(u64, context[0..8]); | |
| 436 | d.h[7] ^= mem.readIntLittle(u64, context[8..16]); | |
| 437 | } | |
| 438 | if (key_len > 0) { | |
| 439 | mem.set(u8, d.buf[key_len..], 0); | |
| 440 | d.update(options.key.?); | |
| 434 | 441 | d.buf_len = 128; |
| 435 | 442 | } |
| 443 | return d; | |
| 436 | 444 | } |
| 437 | 445 | |
| 438 | pub fn hash(b: []const u8, out: []u8) void { | |
| 439 | Self.hash_keyed("", b, out); | |
| 440 | } | |
| 441 | ||
| 442 | pub fn hash_keyed(key: []const u8, b: []const u8, out: []u8) void { | |
| 443 | var d = Self.init_keyed(key); | |
| 446 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 447 | var d = Self.init(options); | |
| 444 | 448 | d.update(b); |
| 445 | 449 | d.final(out); |
| 446 | 450 | } |
| ... | ... | @@ -547,7 +551,7 @@ test "blake2b384 single" { |
| 547 | 551 | } |
| 548 | 552 | |
| 549 | 553 | test "blake2b384 streaming" { |
| 550 | var h = Blake2b384.init(); | |
| 554 | var h = Blake2b384.init(.{}); | |
| 551 | 555 | var out: [48]u8 = undefined; |
| 552 | 556 | |
| 553 | 557 | const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100"; |
| ... | ... | @@ -557,12 +561,12 @@ test "blake2b384 streaming" { |
| 557 | 561 | |
| 558 | 562 | const h2 = "6f56a82c8e7ef526dfe182eb5212f7db9df1317e57815dbda46083fc30f54ee6c66ba83be64b302d7cba6ce15bb556f4"; |
| 559 | 563 | |
| 560 | h.reset(); | |
| 564 | h = Blake2b384.init(.{}); | |
| 561 | 565 | h.update("abc"); |
| 562 | 566 | h.final(out[0..]); |
| 563 | 567 | htest.assertEqual(h2, out[0..]); |
| 564 | 568 | |
| 565 | h.reset(); | |
| 569 | h = Blake2b384.init(.{}); | |
| 566 | 570 | h.update("a"); |
| 567 | 571 | h.update("b"); |
| 568 | 572 | h.update("c"); |
| ... | ... | @@ -571,16 +575,36 @@ test "blake2b384 streaming" { |
| 571 | 575 | |
| 572 | 576 | const h3 = "b7283f0172fecbbd7eca32ce10d8a6c06b453cb3cf675b33eb4246f0da2bb94a6c0bdd6eec0b5fd71ec4fd51be80bf4c"; |
| 573 | 577 | |
| 574 | h.reset(); | |
| 578 | h = Blake2b384.init(.{}); | |
| 575 | 579 | h.update("a" ** 64 ++ "b" ** 64); |
| 576 | 580 | h.final(out[0..]); |
| 577 | 581 | htest.assertEqual(h3, out[0..]); |
| 578 | 582 | |
| 579 | h.reset(); | |
| 583 | h = Blake2b384.init(.{}); | |
| 584 | h.update("a" ** 64); | |
| 585 | h.update("b" ** 64); | |
| 586 | h.final(out[0..]); | |
| 587 | htest.assertEqual(h3, out[0..]); | |
| 588 | ||
| 589 | h = Blake2b384.init(.{}); | |
| 580 | 590 | h.update("a" ** 64); |
| 581 | 591 | h.update("b" ** 64); |
| 582 | 592 | h.final(out[0..]); |
| 583 | 593 | htest.assertEqual(h3, out[0..]); |
| 594 | ||
| 595 | const h4 = "934c48fcb197031c71f583d92f98703510805e72142e0b46f5752d1e971bc86c355d556035613ff7a4154b4de09dac5c"; | |
| 596 | ||
| 597 | h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); | |
| 598 | h.update("a" ** 64); | |
| 599 | h.update("b" ** 64); | |
| 600 | h.final(out[0..]); | |
| 601 | htest.assertEqual(h4, out[0..]); | |
| 602 | ||
| 603 | h = Blake2b384.init(.{ .context = [_]u8{0x69} ** 16, .salt = [_]u8{0x42} ** 16 }); | |
| 604 | h.update("a" ** 64); | |
| 605 | h.update("b" ** 64); | |
| 606 | h.final(out[0..]); | |
| 607 | htest.assertEqual(h4, out[0..]); | |
| 584 | 608 | } |
| 585 | 609 | |
| 586 | 610 | test "comptime blake2b384" { |
| ... | ... | @@ -593,7 +617,7 @@ test "comptime blake2b384" { |
| 593 | 617 | |
| 594 | 618 | htest.assertEqualHash(Blake2b384, h1, block[0..]); |
| 595 | 619 | |
| 596 | var h = Blake2b384.init(); | |
| 620 | var h = Blake2b384.init(.{}); | |
| 597 | 621 | h.update(&block); |
| 598 | 622 | h.final(out[0..]); |
| 599 | 623 | |
| ... | ... | @@ -616,7 +640,7 @@ test "blake2b512 single" { |
| 616 | 640 | } |
| 617 | 641 | |
| 618 | 642 | test "blake2b512 streaming" { |
| 619 | var h = Blake2b512.init(); | |
| 643 | var h = Blake2b512.init(.{}); | |
| 620 | 644 | var out: [64]u8 = undefined; |
| 621 | 645 | |
| 622 | 646 | const h1 = "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"; |
| ... | ... | @@ -626,12 +650,12 @@ test "blake2b512 streaming" { |
| 626 | 650 | |
| 627 | 651 | const h2 = "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"; |
| 628 | 652 | |
| 629 | h.reset(); | |
| 653 | h = Blake2b512.init(.{}); | |
| 630 | 654 | h.update("abc"); |
| 631 | 655 | h.final(out[0..]); |
| 632 | 656 | htest.assertEqual(h2, out[0..]); |
| 633 | 657 | |
| 634 | h.reset(); | |
| 658 | h = Blake2b512.init(.{}); | |
| 635 | 659 | h.update("a"); |
| 636 | 660 | h.update("b"); |
| 637 | 661 | h.update("c"); |
| ... | ... | @@ -640,12 +664,12 @@ test "blake2b512 streaming" { |
| 640 | 664 | |
| 641 | 665 | const h3 = "049980af04d6a2cf16b4b49793c3ed7e40732073788806f2c989ebe9547bda0541d63abe298ec8955d08af48ae731f2e8a0bd6d201655a5473b4aa79d211b920"; |
| 642 | 666 | |
| 643 | h.reset(); | |
| 667 | h = Blake2b512.init(.{}); | |
| 644 | 668 | h.update("a" ** 64 ++ "b" ** 64); |
| 645 | 669 | h.final(out[0..]); |
| 646 | 670 | htest.assertEqual(h3, out[0..]); |
| 647 | 671 | |
| 648 | h.reset(); | |
| 672 | h = Blake2b512.init(.{}); | |
| 649 | 673 | h.update("a" ** 64); |
| 650 | 674 | h.update("b" ** 64); |
| 651 | 675 | h.final(out[0..]); |
| ... | ... | @@ -658,16 +682,16 @@ test "blake2b512 keyed" { |
| 658 | 682 | const h1 = "8a978060ccaf582f388f37454363071ac9a67e3a704585fd879fb8a419a447e389c7c6de790faa20a7a7dccf197de736bc5b40b98a930b36df5bee7555750c4d"; |
| 659 | 683 | const key = "secret_key"; |
| 660 | 684 | |
| 661 | Blake2b512.hash_keyed(key, "a" ** 64 ++ "b" ** 64, &out); | |
| 685 | Blake2b512.hash("a" ** 64 ++ "b" ** 64, &out, .{ .key = key }); | |
| 662 | 686 | htest.assertEqual(h1, out[0..]); |
| 663 | 687 | |
| 664 | var h = Blake2b512.init_keyed(key); | |
| 688 | var h = Blake2b512.init(.{ .key = key }); | |
| 665 | 689 | h.update("a" ** 64 ++ "b" ** 64); |
| 666 | 690 | h.final(out[0..]); |
| 667 | 691 | |
| 668 | 692 | htest.assertEqual(h1, out[0..]); |
| 669 | 693 | |
| 670 | h.reset(); | |
| 694 | h = Blake2b512.init(.{ .key = key }); | |
| 671 | 695 | h.update("a" ** 64); |
| 672 | 696 | h.update("b" ** 64); |
| 673 | 697 | h.final(out[0..]); |
| ... | ... | @@ -685,7 +709,7 @@ test "comptime blake2b512" { |
| 685 | 709 | |
| 686 | 710 | htest.assertEqualHash(Blake2b512, h1, block[0..]); |
| 687 | 711 | |
| 688 | var h = Blake2b512.init(); | |
| 712 | var h = Blake2b512.init(.{}); | |
| 689 | 713 | h.update(&block); |
| 690 | 714 | h.final(out[0..]); |
| 691 | 715 |
lib/std/crypto/blake3.zig+24-23| ... | ... | @@ -279,6 +279,9 @@ fn parent_cv( |
| 279 | 279 | |
| 280 | 280 | /// An incremental hasher that can accept any number of writes. |
| 281 | 281 | pub const Blake3 = struct { |
| 282 | pub const Options = struct { key: ?[KEY_LEN]u8 = null }; | |
| 283 | pub const KdfOptions = struct {}; | |
| 284 | ||
| 282 | 285 | chunk_state: ChunkState, |
| 283 | 286 | key: [8]u32, |
| 284 | 287 | cv_stack: [54][8]u32 = undefined, // Space for 54 subtree chaining values: |
| ... | ... | @@ -296,21 +299,20 @@ pub const Blake3 = struct { |
| 296 | 299 | }; |
| 297 | 300 | } |
| 298 | 301 | |
| 299 | /// Construct a new `Blake3` for the regular hash function. | |
| 300 | pub fn init() Blake3 { | |
| 301 | return Blake3.init_internal(IV, 0); | |
| 302 | } | |
| 303 | ||
| 304 | /// Construct a new `Blake3` for the keyed hash function. | |
| 305 | pub fn init_keyed(key: [KEY_LEN]u8) Blake3 { | |
| 306 | var key_words: [8]u32 = undefined; | |
| 307 | words_from_little_endian_bytes(key_words[0..], key[0..]); | |
| 308 | return Blake3.init_internal(key_words, KEYED_HASH); | |
| 302 | /// Construct a new `Blake3` for the hash function, with an optional key | |
| 303 | pub fn init(options: Options) Blake3 { | |
| 304 | if (options.key) |key| { | |
| 305 | var key_words: [8]u32 = undefined; | |
| 306 | words_from_little_endian_bytes(key_words[0..], key[0..]); | |
| 307 | return Blake3.init_internal(key_words, KEYED_HASH); | |
| 308 | } else { | |
| 309 | return Blake3.init_internal(IV, 0); | |
| 310 | } | |
| 309 | 311 | } |
| 310 | 312 | |
| 311 | 313 | /// Construct a new `Blake3` for the key derivation function. The context |
| 312 | 314 | /// string should be hardcoded, globally unique, and application-specific. |
| 313 | pub fn init_derive_key(context: []const u8) Blake3 { | |
| 315 | pub fn initKdf(context: []const u8, options: KdfOptions) Blake3 { | |
| 314 | 316 | var context_hasher = Blake3.init_internal(IV, DERIVE_KEY_CONTEXT); |
| 315 | 317 | context_hasher.update(context); |
| 316 | 318 | var context_key: [KEY_LEN]u8 = undefined; |
| ... | ... | @@ -320,18 +322,12 @@ pub const Blake3 = struct { |
| 320 | 322 | return Blake3.init_internal(context_key_words, DERIVE_KEY_MATERIAL); |
| 321 | 323 | } |
| 322 | 324 | |
| 323 | pub fn hash(in: []const u8, out: []u8) void { | |
| 324 | var hasher = Blake3.init(); | |
| 325 | pub fn hash(in: []const u8, out: []u8, options: Options) void { | |
| 326 | var hasher = Blake3.init(options); | |
| 325 | 327 | hasher.update(in); |
| 326 | 328 | hasher.final(out); |
| 327 | 329 | } |
| 328 | 330 | |
| 329 | /// Reset the `Blake3` to its initial state. | |
| 330 | pub fn reset(self: *Blake3) void { | |
| 331 | self.chunk_state = ChunkState.init(self.key, 0, self.flags); | |
| 332 | self.cv_stack_len = 0; | |
| 333 | } | |
| 334 | ||
| 335 | 331 | fn push_cv(self: *Blake3, cv: [8]u32) void { |
| 336 | 332 | self.cv_stack[self.cv_stack_len] = cv; |
| 337 | 333 | self.cv_stack_len += 1; |
| ... | ... | @@ -566,6 +562,9 @@ const reference_test = ReferenceTest{ |
| 566 | 562 | }; |
| 567 | 563 | |
| 568 | 564 | fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { |
| 565 | // Save initial state | |
| 566 | const initial_state = hasher.*; | |
| 567 | ||
| 569 | 568 | // Setup input pattern |
| 570 | 569 | var input_pattern: [251]u8 = undefined; |
| 571 | 570 | for (input_pattern) |*e, i| e.* = @truncate(u8, i); |
| ... | ... | @@ -581,18 +580,20 @@ fn test_blake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void { |
| 581 | 580 | // Read final hash value |
| 582 | 581 | var actual_bytes: [expected_hex.len / 2]u8 = undefined; |
| 583 | 582 | hasher.final(actual_bytes[0..]); |
| 584 | hasher.reset(); | |
| 585 | 583 | |
| 586 | 584 | // Compare to expected value |
| 587 | 585 | var expected_bytes: [expected_hex.len / 2]u8 = undefined; |
| 588 | 586 | fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable; |
| 589 | 587 | testing.expectEqual(actual_bytes, expected_bytes); |
| 588 | ||
| 589 | // Restore initial state | |
| 590 | hasher.* = initial_state; | |
| 590 | 591 | } |
| 591 | 592 | |
| 592 | 593 | test "BLAKE3 reference test cases" { |
| 593 | var hash = &Blake3.init(); | |
| 594 | var keyed_hash = &Blake3.init_keyed(reference_test.key.*); | |
| 595 | var derive_key = &Blake3.init_derive_key(reference_test.context_string); | |
| 594 | var hash = &Blake3.init(.{}); | |
| 595 | var keyed_hash = &Blake3.init(.{ .key = reference_test.key.* }); | |
| 596 | var derive_key = &Blake3.initKdf(reference_test.context_string, .{}); | |
| 596 | 597 | |
| 597 | 598 | for (reference_test.cases) |t| { |
| 598 | 599 | test_blake3(hash, t.input_len, t.hash.*); |
lib/std/crypto/chacha20.zig+74-68| ... | ... | @@ -12,7 +12,7 @@ const assert = std.debug.assert; |
| 12 | 12 | const testing = std.testing; |
| 13 | 13 | const builtin = @import("builtin"); |
| 14 | 14 | const maxInt = std.math.maxInt; |
| 15 | const Poly1305 = std.crypto.Poly1305; | |
| 15 | const Poly1305 = std.crypto.onetimeauth.Poly1305; | |
| 16 | 16 | |
| 17 | 17 | const QuarterRound = struct { |
| 18 | 18 | a: usize, |
| ... | ... | @@ -137,56 +137,60 @@ fn keyToWords(key: [32]u8) [8]u32 { |
| 137 | 137 | /// |
| 138 | 138 | /// ChaCha20 is self-reversing. To decrypt just run the cipher with the same |
| 139 | 139 | /// counter, nonce, and key. |
| 140 | pub fn chaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void { | |
| 141 | assert(in.len >= out.len); | |
| 142 | assert((in.len >> 6) + counter <= maxInt(u32)); | |
| 143 | ||
| 144 | var c: [4]u32 = undefined; | |
| 145 | c[0] = counter; | |
| 146 | c[1] = mem.readIntLittle(u32, nonce[0..4]); | |
| 147 | c[2] = mem.readIntLittle(u32, nonce[4..8]); | |
| 148 | c[3] = mem.readIntLittle(u32, nonce[8..12]); | |
| 149 | chaCha20_internal(out, in, keyToWords(key), c); | |
| 150 | } | |
| 140 | pub const ChaCha20IETF = struct { | |
| 141 | pub fn xor(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [12]u8) void { | |
| 142 | assert(in.len >= out.len); | |
| 143 | assert((in.len >> 6) + counter <= maxInt(u32)); | |
| 144 | ||
| 145 | var c: [4]u32 = undefined; | |
| 146 | c[0] = counter; | |
| 147 | c[1] = mem.readIntLittle(u32, nonce[0..4]); | |
| 148 | c[2] = mem.readIntLittle(u32, nonce[4..8]); | |
| 149 | c[3] = mem.readIntLittle(u32, nonce[8..12]); | |
| 150 | chaCha20_internal(out, in, keyToWords(key), c); | |
| 151 | } | |
| 152 | }; | |
| 151 | 153 | |
| 152 | 154 | /// This is the original ChaCha20 before RFC 7539, which recommends using the |
| 153 | 155 | /// orgininal version on applications such as disk or file encryption that might |
| 154 | 156 | /// exceed the 256 GiB limit of the 96-bit nonce version. |
| 155 | pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void { | |
| 156 | assert(in.len >= out.len); | |
| 157 | assert(counter +% (in.len >> 6) >= counter); | |
| 158 | ||
| 159 | var cursor: usize = 0; | |
| 160 | const k = keyToWords(key); | |
| 161 | var c: [4]u32 = undefined; | |
| 162 | c[0] = @truncate(u32, counter); | |
| 163 | c[1] = @truncate(u32, counter >> 32); | |
| 164 | c[2] = mem.readIntLittle(u32, nonce[0..4]); | |
| 165 | c[3] = mem.readIntLittle(u32, nonce[4..8]); | |
| 166 | ||
| 167 | const block_size = (1 << 6); | |
| 168 | // The full block size is greater than the address space on a 32bit machine | |
| 169 | const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize); | |
| 170 | ||
| 171 | // first partial big block | |
| 172 | if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) { | |
| 173 | chaCha20_internal(out[cursor..big_block], in[cursor..big_block], k, c); | |
| 174 | cursor = big_block - cursor; | |
| 175 | c[1] += 1; | |
| 176 | if (comptime @sizeOf(usize) > 4) { | |
| 177 | // A big block is giant: 256 GiB, but we can avoid this limitation | |
| 178 | var remaining_blocks: u32 = @intCast(u32, (in.len / big_block)); | |
| 179 | var i: u32 = 0; | |
| 180 | while (remaining_blocks > 0) : (remaining_blocks -= 1) { | |
| 181 | chaCha20_internal(out[cursor .. cursor + big_block], in[cursor .. cursor + big_block], k, c); | |
| 182 | c[1] += 1; // upper 32-bit of counter, generic chaCha20_internal() doesn't know about this. | |
| 183 | cursor += big_block; | |
| 157 | pub const ChaCha20With64BitNonce = struct { | |
| 158 | pub fn xor(out: []u8, in: []const u8, counter: u64, key: [32]u8, nonce: [8]u8) void { | |
| 159 | assert(in.len >= out.len); | |
| 160 | assert(counter +% (in.len >> 6) >= counter); | |
| 161 | ||
| 162 | var cursor: usize = 0; | |
| 163 | const k = keyToWords(key); | |
| 164 | var c: [4]u32 = undefined; | |
| 165 | c[0] = @truncate(u32, counter); | |
| 166 | c[1] = @truncate(u32, counter >> 32); | |
| 167 | c[2] = mem.readIntLittle(u32, nonce[0..4]); | |
| 168 | c[3] = mem.readIntLittle(u32, nonce[4..8]); | |
| 169 | ||
| 170 | const block_size = (1 << 6); | |
| 171 | // The full block size is greater than the address space on a 32bit machine | |
| 172 | const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize); | |
| 173 | ||
| 174 | // first partial big block | |
| 175 | if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) { | |
| 176 | chaCha20_internal(out[cursor..big_block], in[cursor..big_block], k, c); | |
| 177 | cursor = big_block - cursor; | |
| 178 | c[1] += 1; | |
| 179 | if (comptime @sizeOf(usize) > 4) { | |
| 180 | // A big block is giant: 256 GiB, but we can avoid this limitation | |
| 181 | var remaining_blocks: u32 = @intCast(u32, (in.len / big_block)); | |
| 182 | var i: u32 = 0; | |
| 183 | while (remaining_blocks > 0) : (remaining_blocks -= 1) { | |
| 184 | chaCha20_internal(out[cursor .. cursor + big_block], in[cursor .. cursor + big_block], k, c); | |
| 185 | c[1] += 1; // upper 32-bit of counter, generic chaCha20_internal() doesn't know about this. | |
| 186 | cursor += big_block; | |
| 187 | } | |
| 184 | 188 | } |
| 185 | 189 | } |
| 186 | } | |
| 187 | 190 | |
| 188 | chaCha20_internal(out[cursor..], in[cursor..], k, c); | |
| 189 | } | |
| 191 | chaCha20_internal(out[cursor..], in[cursor..], k, c); | |
| 192 | } | |
| 193 | }; | |
| 190 | 194 | |
| 191 | 195 | // https://tools.ietf.org/html/rfc7539#section-2.4.2 |
| 192 | 196 | test "crypto.chacha20 test vector sunscreen" { |
| ... | ... | @@ -221,12 +225,12 @@ test "crypto.chacha20 test vector sunscreen" { |
| 221 | 225 | 0, 0, 0, 0, |
| 222 | 226 | }; |
| 223 | 227 | |
| 224 | chaCha20IETF(result[0..], input[0..], 1, key, nonce); | |
| 228 | ChaCha20IETF.xor(result[0..], input[0..], 1, key, nonce); | |
| 225 | 229 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 226 | 230 | |
| 227 | 231 | // Chacha20 is self-reversing. |
| 228 | 232 | var plaintext: [114]u8 = undefined; |
| 229 | chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce); | |
| 233 | ChaCha20IETF.xor(plaintext[0..], result[0..], 1, key, nonce); | |
| 230 | 234 | testing.expect(mem.order(u8, input, &plaintext) == .eq); |
| 231 | 235 | } |
| 232 | 236 | |
| ... | ... | @@ -261,7 +265,7 @@ test "crypto.chacha20 test vector 1" { |
| 261 | 265 | }; |
| 262 | 266 | const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 263 | 267 | |
| 264 | chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); | |
| 268 | ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); | |
| 265 | 269 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 266 | 270 | } |
| 267 | 271 | |
| ... | ... | @@ -295,7 +299,7 @@ test "crypto.chacha20 test vector 2" { |
| 295 | 299 | }; |
| 296 | 300 | const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 297 | 301 | |
| 298 | chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); | |
| 302 | ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); | |
| 299 | 303 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 300 | 304 | } |
| 301 | 305 | |
| ... | ... | @@ -329,7 +333,7 @@ test "crypto.chacha20 test vector 3" { |
| 329 | 333 | }; |
| 330 | 334 | const nonce = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 1 }; |
| 331 | 335 | |
| 332 | chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); | |
| 336 | ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); | |
| 333 | 337 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 334 | 338 | } |
| 335 | 339 | |
| ... | ... | @@ -363,7 +367,7 @@ test "crypto.chacha20 test vector 4" { |
| 363 | 367 | }; |
| 364 | 368 | const nonce = [_]u8{ 1, 0, 0, 0, 0, 0, 0, 0 }; |
| 365 | 369 | |
| 366 | chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); | |
| 370 | ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); | |
| 367 | 371 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 368 | 372 | } |
| 369 | 373 | |
| ... | ... | @@ -435,21 +439,21 @@ test "crypto.chacha20 test vector 5" { |
| 435 | 439 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 436 | 440 | }; |
| 437 | 441 | |
| 438 | chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce); | |
| 442 | ChaCha20With64BitNonce.xor(result[0..], input[0..], 0, key, nonce); | |
| 439 | 443 | testing.expectEqualSlices(u8, &expected_result, &result); |
| 440 | 444 | } |
| 441 | 445 | |
| 442 | 446 | pub const chacha20poly1305_tag_size = 16; |
| 443 | 447 | |
| 444 | pub fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { | |
| 448 | fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { | |
| 445 | 449 | assert(ciphertext.len >= plaintext.len); |
| 446 | 450 | |
| 447 | 451 | // derive poly1305 key |
| 448 | 452 | var polyKey = [_]u8{0} ** 32; |
| 449 | chaCha20IETF(polyKey[0..], polyKey[0..], 0, key, nonce); | |
| 453 | ChaCha20IETF.xor(polyKey[0..], polyKey[0..], 0, key, nonce); | |
| 450 | 454 | |
| 451 | 455 | // encrypt plaintext |
| 452 | chaCha20IETF(ciphertext[0..plaintext.len], plaintext, 1, key, nonce); | |
| 456 | ChaCha20IETF.xor(ciphertext[0..plaintext.len], plaintext, 1, key, nonce); | |
| 453 | 457 | |
| 454 | 458 | // construct mac |
| 455 | 459 | var mac = Poly1305.init(polyKey[0..]); |
| ... | ... | @@ -472,18 +476,18 @@ pub fn chacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_ta |
| 472 | 476 | mac.final(tag); |
| 473 | 477 | } |
| 474 | 478 | |
| 475 | pub fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { | |
| 479 | fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) void { | |
| 476 | 480 | return chacha20poly1305SealDetached(ciphertextAndTag[0..plaintext.len], ciphertextAndTag[plaintext.len..][0..chacha20poly1305_tag_size], plaintext, data, key, nonce); |
| 477 | 481 | } |
| 478 | 482 | |
| 479 | 483 | /// Verifies and decrypts an authenticated message produced by chacha20poly1305SealDetached. |
| 480 | pub fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { | |
| 484 | fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { | |
| 481 | 485 | // split ciphertext and tag |
| 482 | 486 | assert(dst.len >= ciphertext.len); |
| 483 | 487 | |
| 484 | 488 | // derive poly1305 key |
| 485 | 489 | var polyKey = [_]u8{0} ** 32; |
| 486 | chaCha20IETF(polyKey[0..], polyKey[0..], 0, key, nonce); | |
| 490 | ChaCha20IETF.xor(polyKey[0..], polyKey[0..], 0, key, nonce); | |
| 487 | 491 | |
| 488 | 492 | // construct mac |
| 489 | 493 | var mac = Poly1305.init(polyKey[0..]); |
| ... | ... | @@ -519,11 +523,11 @@ pub fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *con |
| 519 | 523 | } |
| 520 | 524 | |
| 521 | 525 | // decrypt ciphertext |
| 522 | chaCha20IETF(dst[0..ciphertext.len], ciphertext, 1, key, nonce); | |
| 526 | ChaCha20IETF.xor(dst[0..ciphertext.len], ciphertext, 1, key, nonce); | |
| 523 | 527 | } |
| 524 | 528 | |
| 525 | 529 | /// Verifies and decrypts an authenticated message produced by chacha20poly1305Seal. |
| 526 | pub fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { | |
| 530 | fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void { | |
| 527 | 531 | if (ciphertextAndTag.len < chacha20poly1305_tag_size) { |
| 528 | 532 | return error.InvalidMessage; |
| 529 | 533 | } |
| ... | ... | @@ -562,31 +566,33 @@ fn extend(key: [32]u8, nonce: [24]u8) struct { key: [32]u8, nonce: [12]u8 } { |
| 562 | 566 | }; |
| 563 | 567 | } |
| 564 | 568 | |
| 565 | pub fn xChaCha20IETF(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [24]u8) void { | |
| 566 | const extended = extend(key, nonce); | |
| 567 | chaCha20IETF(out, in, counter, extended.key, extended.nonce); | |
| 568 | } | |
| 569 | pub const XChaCha20IETF = struct { | |
| 570 | pub fn xor(out: []u8, in: []const u8, counter: u32, key: [32]u8, nonce: [24]u8) void { | |
| 571 | const extended = extend(key, nonce); | |
| 572 | ChaCha20IETF.xor(out, in, counter, extended.key, extended.nonce); | |
| 573 | } | |
| 574 | }; | |
| 569 | 575 | |
| 570 | 576 | pub const xchacha20poly1305_tag_size = 16; |
| 571 | 577 | |
| 572 | pub fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { | |
| 578 | fn xchacha20poly1305SealDetached(ciphertext: []u8, tag: *[chacha20poly1305_tag_size]u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { | |
| 573 | 579 | const extended = extend(key, nonce); |
| 574 | 580 | return chacha20poly1305SealDetached(ciphertext, tag, plaintext, data, extended.key, extended.nonce); |
| 575 | 581 | } |
| 576 | 582 | |
| 577 | pub fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { | |
| 583 | fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) void { | |
| 578 | 584 | const extended = extend(key, nonce); |
| 579 | 585 | return chacha20poly1305Seal(ciphertextAndTag, plaintext, data, extended.key, extended.nonce); |
| 580 | 586 | } |
| 581 | 587 | |
| 582 | 588 | /// Verifies and decrypts an authenticated message produced by xchacha20poly1305SealDetached. |
| 583 | pub fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { | |
| 589 | fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_size]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { | |
| 584 | 590 | const extended = extend(key, nonce); |
| 585 | 591 | return try chacha20poly1305OpenDetached(plaintext, ciphertext, tag, data, extended.key, extended.nonce); |
| 586 | 592 | } |
| 587 | 593 | |
| 588 | 594 | /// Verifies and decrypts an authenticated message produced by xchacha20poly1305Seal. |
| 589 | pub fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { | |
| 595 | fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void { | |
| 590 | 596 | const extended = extend(key, nonce); |
| 591 | 597 | return try chacha20poly1305Open(ciphertextAndTag, msgAndTag, data, extended.key, extended.nonce); |
| 592 | 598 | } |
| ... | ... | @@ -714,7 +720,7 @@ test "crypto.xchacha20" { |
| 714 | 720 | const input = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; |
| 715 | 721 | { |
| 716 | 722 | var ciphertext: [input.len]u8 = undefined; |
| 717 | xChaCha20IETF(ciphertext[0..], input[0..], 0, key, nonce); | |
| 723 | XChaCha20IETF.xor(ciphertext[0..], input[0..], 0, key, nonce); | |
| 718 | 724 | var buf: [2 * ciphertext.len]u8 = undefined; |
| 719 | 725 | testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{ciphertext}), "E0A1BCF939654AFDBDC1746EC49832647C19D891F0D1A81FC0C1703B4514BDEA584B512F6908C2C5E9DD18D5CBC1805DE5803FE3B9CA5F193FB8359E91FAB0C3BB40309A292EB1CF49685C65C4A3ADF4F11DB0CD2B6B67FBC174BC2E860E8F769FD3565BBFAD1C845E05A0FED9BE167C240D"); |
| 720 | 726 | } |
lib/std/crypto/gimli.zig+8-7| ... | ... | @@ -109,13 +109,14 @@ pub const Hash = struct { |
| 109 | 109 | state: State, |
| 110 | 110 | buf_off: usize, |
| 111 | 111 | |
| 112 | pub const block_length = State.RATE; | |
| 113 | pub const Options = struct {}; | |
| 114 | ||
| 112 | 115 | const Self = @This(); |
| 113 | 116 | |
| 114 | pub fn init() Self { | |
| 117 | pub fn init(options: Options) Self { | |
| 115 | 118 | return Self{ |
| 116 | .state = State{ | |
| 117 | .data = [_]u32{0} ** (State.BLOCKBYTES / 4), | |
| 118 | }, | |
| 119 | .state = State{ .data = [_]u32{0} ** (State.BLOCKBYTES / 4) }, | |
| 119 | 120 | .buf_off = 0, |
| 120 | 121 | }; |
| 121 | 122 | } |
| ... | ... | @@ -160,8 +161,8 @@ pub const Hash = struct { |
| 160 | 161 | } |
| 161 | 162 | }; |
| 162 | 163 | |
| 163 | pub fn hash(out: []u8, in: []const u8) void { | |
| 164 | var st = Hash.init(); | |
| 164 | pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void { | |
| 165 | var st = Hash.init(options); | |
| 165 | 166 | st.update(in); |
| 166 | 167 | st.final(out); |
| 167 | 168 | } |
| ... | ... | @@ -174,7 +175,7 @@ test "hash" { |
| 174 | 175 | var msg: [58 / 2]u8 = undefined; |
| 175 | 176 | try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C"); |
| 176 | 177 | var md: [32]u8 = undefined; |
| 177 | hash(&md, &msg); | |
| 178 | hash(&md, &msg, .{}); | |
| 178 | 179 | htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md); |
| 179 | 180 | } |
| 180 | 181 |
lib/std/crypto/hmac.zig+22-13| ... | ... | @@ -8,10 +8,19 @@ const crypto = std.crypto; |
| 8 | 8 | const debug = std.debug; |
| 9 | 9 | const mem = std.mem; |
| 10 | 10 | |
| 11 | pub const HmacMd5 = Hmac(crypto.Md5); | |
| 12 | pub const HmacSha1 = Hmac(crypto.Sha1); | |
| 13 | pub const HmacSha256 = Hmac(crypto.Sha256); | |
| 14 | pub const HmacBlake2s256 = Hmac(crypto.Blake2s256); | |
| 11 | pub const HmacMd5 = Hmac(crypto.hash.Md5); | |
| 12 | pub const HmacSha1 = Hmac(crypto.hash.Sha1); | |
| 13 | ||
| 14 | pub const sha2 = struct { | |
| 15 | pub const HmacSha224 = Hmac(crypto.hash.sha2.Sha224); | |
| 16 | pub const HmacSha256 = Hmac(crypto.hash.sha2.Sha256); | |
| 17 | pub const HmacSha384 = Hmac(crypto.hash.sha2.Sha384); | |
| 18 | pub const HmacSha512 = Hmac(crypto.hash.sha2.Sha512); | |
| 19 | }; | |
| 20 | ||
| 21 | pub const blake2 = struct { | |
| 22 | pub const HmacBlake2s256 = Hmac(crypto.hash.blake2.Blake2s256); | |
| 23 | }; | |
| 15 | 24 | |
| 16 | 25 | pub fn Hmac(comptime Hash: type) type { |
| 17 | 26 | return struct { |
| ... | ... | @@ -36,7 +45,7 @@ pub fn Hmac(comptime Hash: type) type { |
| 36 | 45 | |
| 37 | 46 | // Normalize key length to block size of hash |
| 38 | 47 | if (key.len > Hash.block_length) { |
| 39 | Hash.hash(key, ctx.scratch[0..mac_length]); | |
| 48 | Hash.hash(key, ctx.scratch[0..mac_length], .{}); | |
| 40 | 49 | mem.set(u8, ctx.scratch[mac_length..Hash.block_length], 0); |
| 41 | 50 | } else if (key.len < Hash.block_length) { |
| 42 | 51 | mem.copy(u8, ctx.scratch[0..key.len], key); |
| ... | ... | @@ -53,7 +62,7 @@ pub fn Hmac(comptime Hash: type) type { |
| 53 | 62 | b.* = ctx.scratch[i] ^ 0x36; |
| 54 | 63 | } |
| 55 | 64 | |
| 56 | ctx.hash = Hash.init(); | |
| 65 | ctx.hash = Hash.init(.{}); | |
| 57 | 66 | ctx.hash.update(ctx.i_key_pad[0..]); |
| 58 | 67 | return ctx; |
| 59 | 68 | } |
| ... | ... | @@ -66,10 +75,10 @@ pub fn Hmac(comptime Hash: type) type { |
| 66 | 75 | debug.assert(Hash.block_length >= out.len and out.len >= mac_length); |
| 67 | 76 | |
| 68 | 77 | ctx.hash.final(ctx.scratch[0..mac_length]); |
| 69 | ctx.hash.reset(); | |
| 70 | ctx.hash.update(ctx.o_key_pad[0..]); | |
| 71 | ctx.hash.update(ctx.scratch[0..mac_length]); | |
| 72 | ctx.hash.final(out[0..mac_length]); | |
| 78 | var ohash = Hash.init(.{}); | |
| 79 | ohash.update(ctx.o_key_pad[0..]); | |
| 80 | ohash.update(ctx.scratch[0..mac_length]); | |
| 81 | ohash.final(out[0..mac_length]); | |
| 73 | 82 | } |
| 74 | 83 | }; |
| 75 | 84 | } |
| ... | ... | @@ -95,10 +104,10 @@ test "hmac sha1" { |
| 95 | 104 | } |
| 96 | 105 | |
| 97 | 106 | test "hmac sha256" { |
| 98 | var out: [HmacSha256.mac_length]u8 = undefined; | |
| 99 | HmacSha256.create(out[0..], "", ""); | |
| 107 | var out: [sha2.HmacSha256.mac_length]u8 = undefined; | |
| 108 | sha2.HmacSha256.create(out[0..], "", ""); | |
| 100 | 109 | htest.assertEqual("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", out[0..]); |
| 101 | 110 | |
| 102 | HmacSha256.create(out[0..], "The quick brown fox jumps over the lazy dog", "key"); | |
| 111 | sha2.HmacSha256.create(out[0..], "The quick brown fox jumps over the lazy dog", "key"); | |
| 103 | 112 | htest.assertEqual("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8", out[0..]); |
| 104 | 113 | } |
lib/std/crypto/md5.zig+22-19| ... | ... | @@ -32,10 +32,14 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundPar |
| 32 | 32 | }; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | /// The MD5 function is now considered cryptographically broken. | |
| 36 | /// Namely, it is trivial to find multiple inputs producing the same hash. | |
| 37 | /// For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. | |
| 35 | 38 | pub const Md5 = struct { |
| 36 | 39 | const Self = @This(); |
| 37 | 40 | pub const block_length = 64; |
| 38 | 41 | pub const digest_length = 16; |
| 42 | pub const Options = struct {}; | |
| 39 | 43 | |
| 40 | 44 | s: [4]u32, |
| 41 | 45 | // Streaming Cache |
| ... | ... | @@ -43,23 +47,22 @@ pub const Md5 = struct { |
| 43 | 47 | buf_len: u8, |
| 44 | 48 | total_len: u64, |
| 45 | 49 | |
| 46 | pub fn init() Self { | |
| 47 | var d: Self = undefined; | |
| 48 | d.reset(); | |
| 49 | return d; | |
| 50 | } | |
| 51 | ||
| 52 | pub fn reset(d: *Self) void { | |
| 53 | d.s[0] = 0x67452301; | |
| 54 | d.s[1] = 0xEFCDAB89; | |
| 55 | d.s[2] = 0x98BADCFE; | |
| 56 | d.s[3] = 0x10325476; | |
| 57 | d.buf_len = 0; | |
| 58 | d.total_len = 0; | |
| 50 | pub fn init(options: Options) Self { | |
| 51 | return Self{ | |
| 52 | .s = [_]u32{ | |
| 53 | 0x67452301, | |
| 54 | 0xEFCDAB89, | |
| 55 | 0x98BADCFE, | |
| 56 | 0x10325476, | |
| 57 | }, | |
| 58 | .buf = undefined, | |
| 59 | .buf_len = 0, | |
| 60 | .total_len = 0, | |
| 61 | }; | |
| 59 | 62 | } |
| 60 | 63 | |
| 61 | pub fn hash(b: []const u8, out: []u8) void { | |
| 62 | var d = Md5.init(); | |
| 64 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 65 | var d = Md5.init(options); | |
| 63 | 66 | d.update(b); |
| 64 | 67 | d.final(out); |
| 65 | 68 | } |
| ... | ... | @@ -255,18 +258,18 @@ test "md5 single" { |
| 255 | 258 | } |
| 256 | 259 | |
| 257 | 260 | test "md5 streaming" { |
| 258 | var h = Md5.init(); | |
| 261 | var h = Md5.init(.{}); | |
| 259 | 262 | var out: [16]u8 = undefined; |
| 260 | 263 | |
| 261 | 264 | h.final(out[0..]); |
| 262 | 265 | htest.assertEqual("d41d8cd98f00b204e9800998ecf8427e", out[0..]); |
| 263 | 266 | |
| 264 | h.reset(); | |
| 267 | h = Md5.init(.{}); | |
| 265 | 268 | h.update("abc"); |
| 266 | 269 | h.final(out[0..]); |
| 267 | 270 | htest.assertEqual("900150983cd24fb0d6963f7d28e17f72", out[0..]); |
| 268 | 271 | |
| 269 | h.reset(); | |
| 272 | h = Md5.init(.{}); | |
| 270 | 273 | h.update("a"); |
| 271 | 274 | h.update("b"); |
| 272 | 275 | h.update("c"); |
| ... | ... | @@ -279,7 +282,7 @@ test "md5 aligned final" { |
| 279 | 282 | var block = [_]u8{0} ** Md5.block_length; |
| 280 | 283 | var out: [Md5.digest_length]u8 = undefined; |
| 281 | 284 | |
| 282 | var h = Md5.init(); | |
| 285 | var h = Md5.init(.{}); | |
| 283 | 286 | h.update(&block); |
| 284 | 287 | h.final(out[0..]); |
| 285 | 288 | } |
lib/std/crypto/sha1.zig+24-24| ... | ... | @@ -29,35 +29,35 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { |
| 29 | 29 | }; |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | /// The SHA-1 function is now considered cryptographically broken. | |
| 33 | /// Namely, it is feasible to find multiple inputs producing the same hash. | |
| 34 | /// For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. | |
| 32 | 35 | pub const Sha1 = struct { |
| 33 | 36 | const Self = @This(); |
| 34 | 37 | pub const block_length = 64; |
| 35 | 38 | pub const digest_length = 20; |
| 39 | pub const Options = struct {}; | |
| 36 | 40 | |
| 37 | 41 | s: [5]u32, |
| 38 | 42 | // Streaming Cache |
| 39 | buf: [64]u8, | |
| 40 | buf_len: u8, | |
| 41 | total_len: u64, | |
| 42 | ||
| 43 | pub fn init() Self { | |
| 44 | var d: Self = undefined; | |
| 45 | d.reset(); | |
| 46 | return d; | |
| 47 | } | |
| 48 | ||
| 49 | pub fn reset(d: *Self) void { | |
| 50 | d.s[0] = 0x67452301; | |
| 51 | d.s[1] = 0xEFCDAB89; | |
| 52 | d.s[2] = 0x98BADCFE; | |
| 53 | d.s[3] = 0x10325476; | |
| 54 | d.s[4] = 0xC3D2E1F0; | |
| 55 | d.buf_len = 0; | |
| 56 | d.total_len = 0; | |
| 43 | buf: [64]u8 = undefined, | |
| 44 | buf_len: u8 = 0, | |
| 45 | total_len: u64 = 0, | |
| 46 | ||
| 47 | pub fn init(options: Options) Self { | |
| 48 | return Self{ | |
| 49 | .s = [_]u32{ | |
| 50 | 0x67452301, | |
| 51 | 0xEFCDAB89, | |
| 52 | 0x98BADCFE, | |
| 53 | 0x10325476, | |
| 54 | 0xC3D2E1F0, | |
| 55 | }, | |
| 56 | }; | |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | pub fn hash(b: []const u8, out: []u8) void { | |
| 60 | var d = Sha1.init(); | |
| 59 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 60 | var d = Sha1.init(options); | |
| 61 | 61 | d.update(b); |
| 62 | 62 | d.final(out); |
| 63 | 63 | } |
| ... | ... | @@ -277,18 +277,18 @@ test "sha1 single" { |
| 277 | 277 | } |
| 278 | 278 | |
| 279 | 279 | test "sha1 streaming" { |
| 280 | var h = Sha1.init(); | |
| 280 | var h = Sha1.init(.{}); | |
| 281 | 281 | var out: [20]u8 = undefined; |
| 282 | 282 | |
| 283 | 283 | h.final(out[0..]); |
| 284 | 284 | htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); |
| 285 | 285 | |
| 286 | h.reset(); | |
| 286 | h = Sha1.init(.{}); | |
| 287 | 287 | h.update("abc"); |
| 288 | 288 | h.final(out[0..]); |
| 289 | 289 | htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); |
| 290 | 290 | |
| 291 | h.reset(); | |
| 291 | h = Sha1.init(.{}); | |
| 292 | 292 | h.update("a"); |
| 293 | 293 | h.update("b"); |
| 294 | 294 | h.update("c"); |
| ... | ... | @@ -300,7 +300,7 @@ test "sha1 aligned final" { |
| 300 | 300 | var block = [_]u8{0} ** Sha1.block_length; |
| 301 | 301 | var out: [Sha1.digest_length]u8 = undefined; |
| 302 | 302 | |
| 303 | var h = Sha1.init(); | |
| 303 | var h = Sha1.init(.{}); | |
| 304 | 304 | h.update(&block); |
| 305 | 305 | h.final(out[0..]); |
| 306 | 306 | } |
lib/std/crypto/sha2.zig+90-60| ... | ... | @@ -77,7 +77,10 @@ const Sha256Params = Sha2Params32{ |
| 77 | 77 | .out_len = 256, |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | /// SHA-224 | |
| 80 | 81 | pub const Sha224 = Sha2_32(Sha224Params); |
| 82 | ||
| 83 | /// SHA-256 | |
| 81 | 84 | pub const Sha256 = Sha2_32(Sha256Params); |
| 82 | 85 | |
| 83 | 86 | fn Sha2_32(comptime params: Sha2Params32) type { |
| ... | ... | @@ -85,34 +88,31 @@ fn Sha2_32(comptime params: Sha2Params32) type { |
| 85 | 88 | const Self = @This(); |
| 86 | 89 | pub const block_length = 64; |
| 87 | 90 | pub const digest_length = params.out_len / 8; |
| 91 | pub const Options = struct {}; | |
| 88 | 92 | |
| 89 | 93 | s: [8]u32, |
| 90 | 94 | // Streaming Cache |
| 91 | buf: [64]u8, | |
| 92 | buf_len: u8, | |
| 93 | total_len: u64, | |
| 94 | ||
| 95 | pub fn init() Self { | |
| 96 | var d: Self = undefined; | |
| 97 | d.reset(); | |
| 98 | return d; | |
| 99 | } | |
| 100 | ||
| 101 | pub fn reset(d: *Self) void { | |
| 102 | d.s[0] = params.iv0; | |
| 103 | d.s[1] = params.iv1; | |
| 104 | d.s[2] = params.iv2; | |
| 105 | d.s[3] = params.iv3; | |
| 106 | d.s[4] = params.iv4; | |
| 107 | d.s[5] = params.iv5; | |
| 108 | d.s[6] = params.iv6; | |
| 109 | d.s[7] = params.iv7; | |
| 110 | d.buf_len = 0; | |
| 111 | d.total_len = 0; | |
| 95 | buf: [64]u8 = undefined, | |
| 96 | buf_len: u8 = 0, | |
| 97 | total_len: u64 = 0, | |
| 98 | ||
| 99 | pub fn init(options: Options) Self { | |
| 100 | return Self{ | |
| 101 | .s = [_]u32{ | |
| 102 | params.iv0, | |
| 103 | params.iv1, | |
| 104 | params.iv2, | |
| 105 | params.iv3, | |
| 106 | params.iv4, | |
| 107 | params.iv5, | |
| 108 | params.iv6, | |
| 109 | params.iv7, | |
| 110 | }, | |
| 111 | }; | |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | pub fn hash(b: []const u8, out: []u8) void { | |
| 115 | var d = Self.init(); | |
| 114 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 115 | var d = Self.init(options); | |
| 116 | 116 | d.update(b); |
| 117 | 117 | d.final(out); |
| 118 | 118 | } |
| ... | ... | @@ -297,18 +297,18 @@ test "sha224 single" { |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | test "sha224 streaming" { |
| 300 | var h = Sha224.init(); | |
| 300 | var h = Sha224.init(.{}); | |
| 301 | 301 | var out: [28]u8 = undefined; |
| 302 | 302 | |
| 303 | 303 | h.final(out[0..]); |
| 304 | 304 | htest.assertEqual("d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", out[0..]); |
| 305 | 305 | |
| 306 | h.reset(); | |
| 306 | h = Sha224.init(.{}); | |
| 307 | 307 | h.update("abc"); |
| 308 | 308 | h.final(out[0..]); |
| 309 | 309 | htest.assertEqual("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", out[0..]); |
| 310 | 310 | |
| 311 | h.reset(); | |
| 311 | h = Sha224.init(.{}); | |
| 312 | 312 | h.update("a"); |
| 313 | 313 | h.update("b"); |
| 314 | 314 | h.update("c"); |
| ... | ... | @@ -323,18 +323,18 @@ test "sha256 single" { |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | 325 | test "sha256 streaming" { |
| 326 | var h = Sha256.init(); | |
| 326 | var h = Sha256.init(.{}); | |
| 327 | 327 | var out: [32]u8 = undefined; |
| 328 | 328 | |
| 329 | 329 | h.final(out[0..]); |
| 330 | 330 | htest.assertEqual("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", out[0..]); |
| 331 | 331 | |
| 332 | h.reset(); | |
| 332 | h = Sha256.init(.{}); | |
| 333 | 333 | h.update("abc"); |
| 334 | 334 | h.final(out[0..]); |
| 335 | 335 | htest.assertEqual("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", out[0..]); |
| 336 | 336 | |
| 337 | h.reset(); | |
| 337 | h = Sha256.init(.{}); | |
| 338 | 338 | h.update("a"); |
| 339 | 339 | h.update("b"); |
| 340 | 340 | h.update("c"); |
| ... | ... | @@ -346,7 +346,7 @@ test "sha256 aligned final" { |
| 346 | 346 | var block = [_]u8{0} ** Sha256.block_length; |
| 347 | 347 | var out: [Sha256.digest_length]u8 = undefined; |
| 348 | 348 | |
| 349 | var h = Sha256.init(); | |
| 349 | var h = Sha256.init(.{}); | |
| 350 | 350 | h.update(&block); |
| 351 | 351 | h.final(out[0..]); |
| 352 | 352 | } |
| ... | ... | @@ -418,42 +418,72 @@ const Sha512Params = Sha2Params64{ |
| 418 | 418 | .out_len = 512, |
| 419 | 419 | }; |
| 420 | 420 | |
| 421 | const Sha512256Params = Sha2Params64{ | |
| 422 | .iv0 = 0x22312194FC2BF72C, | |
| 423 | .iv1 = 0x9F555FA3C84C64C2, | |
| 424 | .iv2 = 0x2393B86B6F53B151, | |
| 425 | .iv3 = 0x963877195940EABD, | |
| 426 | .iv4 = 0x96283EE2A88EFFE3, | |
| 427 | .iv5 = 0xBE5E1E2553863992, | |
| 428 | .iv6 = 0x2B0199FC2C85B8AA, | |
| 429 | .iv7 = 0x0EB72DDC81C52CA2, | |
| 430 | .out_len = 256, | |
| 431 | }; | |
| 432 | ||
| 433 | const Sha512T256Params = Sha2Params64{ | |
| 434 | .iv0 = 0x6A09E667F3BCC908, | |
| 435 | .iv1 = 0xBB67AE8584CAA73B, | |
| 436 | .iv2 = 0x3C6EF372FE94F82B, | |
| 437 | .iv3 = 0xA54FF53A5F1D36F1, | |
| 438 | .iv4 = 0x510E527FADE682D1, | |
| 439 | .iv5 = 0x9B05688C2B3E6C1F, | |
| 440 | .iv6 = 0x1F83D9ABFB41BD6B, | |
| 441 | .iv7 = 0x5BE0CD19137E2179, | |
| 442 | .out_len = 256, | |
| 443 | }; | |
| 444 | ||
| 445 | /// SHA-384 | |
| 421 | 446 | pub const Sha384 = Sha2_64(Sha384Params); |
| 447 | ||
| 448 | /// SHA-512 | |
| 422 | 449 | pub const Sha512 = Sha2_64(Sha512Params); |
| 423 | 450 | |
| 451 | /// SHA-512/256 | |
| 452 | pub const Sha512256 = Sha2_64(Sha512256Params); | |
| 453 | ||
| 454 | /// Truncated SHA-512 | |
| 455 | pub const Sha512T256 = Sha2_64(Sha512T256Params); | |
| 456 | ||
| 424 | 457 | fn Sha2_64(comptime params: Sha2Params64) type { |
| 425 | 458 | return struct { |
| 426 | 459 | const Self = @This(); |
| 427 | 460 | pub const block_length = 128; |
| 428 | 461 | pub const digest_length = params.out_len / 8; |
| 462 | pub const Options = struct {}; | |
| 429 | 463 | |
| 430 | 464 | s: [8]u64, |
| 431 | 465 | // Streaming Cache |
| 432 | buf: [128]u8, | |
| 433 | buf_len: u8, | |
| 434 | total_len: u128, | |
| 435 | ||
| 436 | pub fn init() Self { | |
| 437 | var d: Self = undefined; | |
| 438 | d.reset(); | |
| 439 | return d; | |
| 440 | } | |
| 441 | ||
| 442 | pub fn reset(d: *Self) void { | |
| 443 | d.s[0] = params.iv0; | |
| 444 | d.s[1] = params.iv1; | |
| 445 | d.s[2] = params.iv2; | |
| 446 | d.s[3] = params.iv3; | |
| 447 | d.s[4] = params.iv4; | |
| 448 | d.s[5] = params.iv5; | |
| 449 | d.s[6] = params.iv6; | |
| 450 | d.s[7] = params.iv7; | |
| 451 | d.buf_len = 0; | |
| 452 | d.total_len = 0; | |
| 466 | buf: [128]u8 = undefined, | |
| 467 | buf_len: u8 = 0, | |
| 468 | total_len: u128 = 0, | |
| 469 | ||
| 470 | pub fn init(options: Options) Self { | |
| 471 | return Self{ | |
| 472 | .s = [_]u64{ | |
| 473 | params.iv0, | |
| 474 | params.iv1, | |
| 475 | params.iv2, | |
| 476 | params.iv3, | |
| 477 | params.iv4, | |
| 478 | params.iv5, | |
| 479 | params.iv6, | |
| 480 | params.iv7, | |
| 481 | }, | |
| 482 | }; | |
| 453 | 483 | } |
| 454 | 484 | |
| 455 | pub fn hash(b: []const u8, out: []u8) void { | |
| 456 | var d = Self.init(); | |
| 485 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 486 | var d = Self.init(options); | |
| 457 | 487 | d.update(b); |
| 458 | 488 | d.final(out); |
| 459 | 489 | } |
| ... | ... | @@ -665,7 +695,7 @@ test "sha384 single" { |
| 665 | 695 | } |
| 666 | 696 | |
| 667 | 697 | test "sha384 streaming" { |
| 668 | var h = Sha384.init(); | |
| 698 | var h = Sha384.init(.{}); | |
| 669 | 699 | var out: [48]u8 = undefined; |
| 670 | 700 | |
| 671 | 701 | const h1 = "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"; |
| ... | ... | @@ -674,12 +704,12 @@ test "sha384 streaming" { |
| 674 | 704 | |
| 675 | 705 | const h2 = "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"; |
| 676 | 706 | |
| 677 | h.reset(); | |
| 707 | h = Sha384.init(.{}); | |
| 678 | 708 | h.update("abc"); |
| 679 | 709 | h.final(out[0..]); |
| 680 | 710 | htest.assertEqual(h2, out[0..]); |
| 681 | 711 | |
| 682 | h.reset(); | |
| 712 | h = Sha384.init(.{}); | |
| 683 | 713 | h.update("a"); |
| 684 | 714 | h.update("b"); |
| 685 | 715 | h.update("c"); |
| ... | ... | @@ -699,7 +729,7 @@ test "sha512 single" { |
| 699 | 729 | } |
| 700 | 730 | |
| 701 | 731 | test "sha512 streaming" { |
| 702 | var h = Sha512.init(); | |
| 732 | var h = Sha512.init(.{}); | |
| 703 | 733 | var out: [64]u8 = undefined; |
| 704 | 734 | |
| 705 | 735 | const h1 = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"; |
| ... | ... | @@ -708,12 +738,12 @@ test "sha512 streaming" { |
| 708 | 738 | |
| 709 | 739 | const h2 = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"; |
| 710 | 740 | |
| 711 | h.reset(); | |
| 741 | h = Sha512.init(.{}); | |
| 712 | 742 | h.update("abc"); |
| 713 | 743 | h.final(out[0..]); |
| 714 | 744 | htest.assertEqual(h2, out[0..]); |
| 715 | 745 | |
| 716 | h.reset(); | |
| 746 | h = Sha512.init(.{}); | |
| 717 | 747 | h.update("a"); |
| 718 | 748 | h.update("b"); |
| 719 | 749 | h.update("c"); |
| ... | ... | @@ -725,7 +755,7 @@ test "sha512 aligned final" { |
| 725 | 755 | var block = [_]u8{0} ** Sha512.block_length; |
| 726 | 756 | var out: [Sha512.digest_length]u8 = undefined; |
| 727 | 757 | |
| 728 | var h = Sha512.init(); | |
| 758 | var h = Sha512.init(.{}); | |
| 729 | 759 | h.update(&block); |
| 730 | 760 | h.final(out[0..]); |
| 731 | 761 | } |
lib/std/crypto/sha3.zig+19-26| ... | ... | @@ -20,25 +20,18 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type { |
| 20 | 20 | const Self = @This(); |
| 21 | 21 | pub const block_length = 200; |
| 22 | 22 | pub const digest_length = bits / 8; |
| 23 | pub const Options = struct {}; | |
| 23 | 24 | |
| 24 | 25 | s: [200]u8, |
| 25 | 26 | offset: usize, |
| 26 | 27 | rate: usize, |
| 27 | 28 | |
| 28 | pub fn init() Self { | |
| 29 | var d: Self = undefined; | |
| 30 | d.reset(); | |
| 31 | return d; | |
| 29 | pub fn init(options: Options) Self { | |
| 30 | return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) }; | |
| 32 | 31 | } |
| 33 | 32 | |
| 34 | pub fn reset(d: *Self) void { | |
| 35 | mem.set(u8, d.s[0..], 0); | |
| 36 | d.offset = 0; | |
| 37 | d.rate = 200 - (bits / 4); | |
| 38 | } | |
| 39 | ||
| 40 | pub fn hash(b: []const u8, out: []u8) void { | |
| 41 | var d = Self.init(); | |
| 33 | pub fn hash(b: []const u8, out: []u8, options: Options) void { | |
| 34 | var d = Self.init(options); | |
| 42 | 35 | d.update(b); |
| 43 | 36 | d.final(out); |
| 44 | 37 | } |
| ... | ... | @@ -183,18 +176,18 @@ test "sha3-224 single" { |
| 183 | 176 | } |
| 184 | 177 | |
| 185 | 178 | test "sha3-224 streaming" { |
| 186 | var h = Sha3_224.init(); | |
| 179 | var h = Sha3_224.init(.{}); | |
| 187 | 180 | var out: [28]u8 = undefined; |
| 188 | 181 | |
| 189 | 182 | h.final(out[0..]); |
| 190 | 183 | htest.assertEqual("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", out[0..]); |
| 191 | 184 | |
| 192 | h.reset(); | |
| 185 | h = Sha3_224.init(.{}); | |
| 193 | 186 | h.update("abc"); |
| 194 | 187 | h.final(out[0..]); |
| 195 | 188 | htest.assertEqual("e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", out[0..]); |
| 196 | 189 | |
| 197 | h.reset(); | |
| 190 | h = Sha3_224.init(.{}); | |
| 198 | 191 | h.update("a"); |
| 199 | 192 | h.update("b"); |
| 200 | 193 | h.update("c"); |
| ... | ... | @@ -209,18 +202,18 @@ test "sha3-256 single" { |
| 209 | 202 | } |
| 210 | 203 | |
| 211 | 204 | test "sha3-256 streaming" { |
| 212 | var h = Sha3_256.init(); | |
| 205 | var h = Sha3_256.init(.{}); | |
| 213 | 206 | var out: [32]u8 = undefined; |
| 214 | 207 | |
| 215 | 208 | h.final(out[0..]); |
| 216 | 209 | htest.assertEqual("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", out[0..]); |
| 217 | 210 | |
| 218 | h.reset(); | |
| 211 | h = Sha3_256.init(.{}); | |
| 219 | 212 | h.update("abc"); |
| 220 | 213 | h.final(out[0..]); |
| 221 | 214 | htest.assertEqual("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", out[0..]); |
| 222 | 215 | |
| 223 | h.reset(); | |
| 216 | h = Sha3_256.init(.{}); | |
| 224 | 217 | h.update("a"); |
| 225 | 218 | h.update("b"); |
| 226 | 219 | h.update("c"); |
| ... | ... | @@ -232,7 +225,7 @@ test "sha3-256 aligned final" { |
| 232 | 225 | var block = [_]u8{0} ** Sha3_256.block_length; |
| 233 | 226 | var out: [Sha3_256.digest_length]u8 = undefined; |
| 234 | 227 | |
| 235 | var h = Sha3_256.init(); | |
| 228 | var h = Sha3_256.init(.{}); | |
| 236 | 229 | h.update(&block); |
| 237 | 230 | h.final(out[0..]); |
| 238 | 231 | } |
| ... | ... | @@ -247,7 +240,7 @@ test "sha3-384 single" { |
| 247 | 240 | } |
| 248 | 241 | |
| 249 | 242 | test "sha3-384 streaming" { |
| 250 | var h = Sha3_384.init(); | |
| 243 | var h = Sha3_384.init(.{}); | |
| 251 | 244 | var out: [48]u8 = undefined; |
| 252 | 245 | |
| 253 | 246 | const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"; |
| ... | ... | @@ -255,12 +248,12 @@ test "sha3-384 streaming" { |
| 255 | 248 | htest.assertEqual(h1, out[0..]); |
| 256 | 249 | |
| 257 | 250 | const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"; |
| 258 | h.reset(); | |
| 251 | h = Sha3_384.init(.{}); | |
| 259 | 252 | h.update("abc"); |
| 260 | 253 | h.final(out[0..]); |
| 261 | 254 | htest.assertEqual(h2, out[0..]); |
| 262 | 255 | |
| 263 | h.reset(); | |
| 256 | h = Sha3_384.init(.{}); | |
| 264 | 257 | h.update("a"); |
| 265 | 258 | h.update("b"); |
| 266 | 259 | h.update("c"); |
| ... | ... | @@ -278,7 +271,7 @@ test "sha3-512 single" { |
| 278 | 271 | } |
| 279 | 272 | |
| 280 | 273 | test "sha3-512 streaming" { |
| 281 | var h = Sha3_512.init(); | |
| 274 | var h = Sha3_512.init(.{}); | |
| 282 | 275 | var out: [64]u8 = undefined; |
| 283 | 276 | |
| 284 | 277 | const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"; |
| ... | ... | @@ -286,12 +279,12 @@ test "sha3-512 streaming" { |
| 286 | 279 | htest.assertEqual(h1, out[0..]); |
| 287 | 280 | |
| 288 | 281 | const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"; |
| 289 | h.reset(); | |
| 282 | h = Sha3_512.init(.{}); | |
| 290 | 283 | h.update("abc"); |
| 291 | 284 | h.final(out[0..]); |
| 292 | 285 | htest.assertEqual(h2, out[0..]); |
| 293 | 286 | |
| 294 | h.reset(); | |
| 287 | h = Sha3_512.init(.{}); | |
| 295 | 288 | h.update("a"); |
| 296 | 289 | h.update("b"); |
| 297 | 290 | h.update("c"); |
| ... | ... | @@ -303,7 +296,7 @@ test "sha3-512 aligned final" { |
| 303 | 296 | var block = [_]u8{0} ** Sha3_512.block_length; |
| 304 | 297 | var out: [Sha3_512.digest_length]u8 = undefined; |
| 305 | 298 | |
| 306 | var h = Sha3_512.init(); | |
| 299 | var h = Sha3_512.init(.{}); | |
| 307 | 300 | h.update(&block); |
| 308 | 301 | h.final(out[0..]); |
| 309 | 302 | } |
lib/std/crypto/test.zig+1-1| ... | ... | @@ -11,7 +11,7 @@ const fmt = std.fmt; |
| 11 | 11 | // Hash using the specified hasher `H` asserting `expected == H(input)`. |
| 12 | 12 | pub fn assertEqualHash(comptime Hasher: anytype, comptime expected: []const u8, input: []const u8) void { |
| 13 | 13 | var h: [expected.len / 2]u8 = undefined; |
| 14 | Hasher.hash(input, h[0..]); | |
| 14 | Hasher.hash(input, h[0..], .{}); | |
| 15 | 15 | |
| 16 | 16 | assertEqual(expected, &h); |
| 17 | 17 | } |
lib/std/rand.zig+2-2| ... | ... | @@ -737,12 +737,12 @@ test "xoroshiro sequence" { |
| 737 | 737 | // CSPRNG |
| 738 | 738 | pub const Gimli = struct { |
| 739 | 739 | random: Random, |
| 740 | state: std.crypto.gimli.State, | |
| 740 | state: std.crypto.core.Gimli, | |
| 741 | 741 | |
| 742 | 742 | pub fn init(init_s: u64) Gimli { |
| 743 | 743 | var self = Gimli{ |
| 744 | 744 | .random = Random{ .fillFn = fill }, |
| 745 | .state = std.crypto.gimli.State{ | |
| 745 | .state = std.crypto.core.Gimli{ | |
| 746 | 746 | .data = [_]u32{0} ** (std.crypto.gimli.State.BLOCKBYTES / 4), |
| 747 | 747 | }, |
| 748 | 748 | }; |
lib/std/zig.zig+1-1| ... | ... | @@ -26,7 +26,7 @@ pub fn hashSrc(src: []const u8) SrcHash { |
| 26 | 26 | std.mem.copy(u8, &out, src); |
| 27 | 27 | std.mem.set(u8, out[src.len..], 0); |
| 28 | 28 | } else { |
| 29 | std.crypto.Blake3.hash(src, &out); | |
| 29 | std.crypto.hash.Blake3.hash(src, &out, .{}); | |
| 30 | 30 | } |
| 31 | 31 | return out; |
| 32 | 32 | } |
tools/process_headers.zig+1-1| ... | ... | @@ -313,7 +313,7 @@ pub fn main() !void { |
| 313 | 313 | var max_bytes_saved: usize = 0; |
| 314 | 314 | var total_bytes: usize = 0; |
| 315 | 315 | |
| 316 | var hasher = std.crypto.Sha256.init(); | |
| 316 | var hasher = std.crypto.hash.sha2.Sha256.init(.{}); | |
| 317 | 317 | |
| 318 | 318 | for (libc_targets) |libc_target| { |
| 319 | 319 | const dest_target = DestTarget{ |