authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2021-03-13 15:11:35+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-14 20:51:31+01:00
logb98d7747fa7fb86d5f3f9bdbd00901e16fc58fca
tree4c054a9bfb1c0d53f5d57a297974e5e0255dc026
parentf69305f865c346ffb2a00403efd0768f8bbdd20b

Use a unified error set for std/crypto/*

This ensures that errors are used consistently across all operations.

18 files changed, 126 insertions(+), 87 deletions(-)

lib/std/crypto.zig+5-1
...@@ -144,6 +144,8 @@ pub const random = &@import("crypto/tlcsprng.zig").interface;...@@ -144,6 +144,8 @@ pub const random = &@import("crypto/tlcsprng.zig").interface;
144144
145const std = @import("std.zig");145const std = @import("std.zig");
146146
147pub const Error = @import("crypto/error.zig").Error;
148
147test "crypto" {149test "crypto" {
148 const please_windows_dont_oom = std.Target.current.os.tag == .windows;150 const please_windows_dont_oom = std.Target.current.os.tag == .windows;
149 if (please_windows_dont_oom) return error.SkipZigTest;151 if (please_windows_dont_oom) return error.SkipZigTest;
...@@ -151,7 +153,9 @@ test "crypto" {...@@ -151,7 +153,9 @@ test "crypto" {
151 inline for (std.meta.declarations(@This())) |decl| {153 inline for (std.meta.declarations(@This())) |decl| {
152 switch (decl.data) {154 switch (decl.data) {
153 .Type => |t| {155 .Type => |t| {
154 std.testing.refAllDecls(t);156 if (@typeInfo(t) != .ErrorSet) {
157 std.testing.refAllDecls(t);
158 }
155 },159 },
156 .Var => |v| {160 .Var => |v| {
157 _ = v;161 _ = v;
lib/std/crypto/25519/curve25519.zig+7-6
...@@ -4,6 +4,7 @@...@@ -4,6 +4,7 @@
4// The MIT license requires this copyright notice to be included in all copies4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.5// and substantial portions of the software.
6const std = @import("std");6const std = @import("std");
7const Error = std.crypto.Error;
78
8/// Group operations over Curve25519.9/// Group operations over Curve25519.
9pub const Curve25519 = struct {10pub const Curve25519 = struct {
...@@ -28,12 +29,12 @@ pub const Curve25519 = struct {...@@ -28,12 +29,12 @@ pub const Curve25519 = struct {
28 pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint };29 pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint };
2930
30 /// Check that the encoding of a Curve25519 point is canonical.31 /// Check that the encoding of a Curve25519 point is canonical.
31 pub fn rejectNonCanonical(s: [32]u8) !void {32 pub fn rejectNonCanonical(s: [32]u8) Error!void {
32 return Fe.rejectNonCanonical(s, false);33 return Fe.rejectNonCanonical(s, false);
33 }34 }
3435
35 /// Reject the neutral element.36 /// Reject the neutral element.
36 pub fn rejectIdentity(p: Curve25519) !void {37 pub fn rejectIdentity(p: Curve25519) Error!void {
37 if (p.x.isZero()) {38 if (p.x.isZero()) {
38 return error.IdentityElement;39 return error.IdentityElement;
39 }40 }
...@@ -44,7 +45,7 @@ pub const Curve25519 = struct {...@@ -44,7 +45,7 @@ pub const Curve25519 = struct {
44 return p.dbl().dbl().dbl();45 return p.dbl().dbl().dbl();
45 }46 }
4647
47 fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) !Curve25519 {48 fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) Error!Curve25519 {
48 var x1 = p.x;49 var x1 = p.x;
49 var x2 = Fe.one;50 var x2 = Fe.one;
50 var z2 = Fe.zero;51 var z2 = Fe.zero;
...@@ -85,7 +86,7 @@ pub const Curve25519 = struct {...@@ -85,7 +86,7 @@ pub const Curve25519 = struct {
85 /// way to use Curve25519 for a DH operation.86 /// way to use Curve25519 for a DH operation.
86 /// Return error.IdentityElement if the resulting point is87 /// Return error.IdentityElement if the resulting point is
87 /// the identity element.88 /// the identity element.
88 pub fn clampedMul(p: Curve25519, s: [32]u8) !Curve25519 {89 pub fn clampedMul(p: Curve25519, s: [32]u8) Error!Curve25519 {
89 var t: [32]u8 = s;90 var t: [32]u8 = s;
90 scalar.clamp(&t);91 scalar.clamp(&t);
91 return try ladder(p, t, 255);92 return try ladder(p, t, 255);
...@@ -95,14 +96,14 @@ pub const Curve25519 = struct {...@@ -95,14 +96,14 @@ pub const Curve25519 = struct {
95 /// Return error.IdentityElement if the resulting point is96 /// Return error.IdentityElement if the resulting point is
96 /// the identity element or error.WeakPublicKey if the public97 /// the identity element or error.WeakPublicKey if the public
97 /// key is a low-order point.98 /// key is a low-order point.
98 pub fn mul(p: Curve25519, s: [32]u8) !Curve25519 {99 pub fn mul(p: Curve25519, s: [32]u8) Error!Curve25519 {
99 const cofactor = [_]u8{8} ++ [_]u8{0} ** 31;100 const cofactor = [_]u8{8} ++ [_]u8{0} ** 31;
100 _ = ladder(p, cofactor, 4) catch |_| return error.WeakPublicKey;101 _ = ladder(p, cofactor, 4) catch |_| return error.WeakPublicKey;
101 return try ladder(p, s, 256);102 return try ladder(p, s, 256);
102 }103 }
103104
104 /// Compute the Curve25519 equivalent to an Edwards25519 point.105 /// Compute the Curve25519 equivalent to an Edwards25519 point.
105 pub fn fromEdwards25519(p: std.crypto.ecc.Edwards25519) !Curve25519 {106 pub fn fromEdwards25519(p: std.crypto.ecc.Edwards25519) Error!Curve25519 {
106 try p.clearCofactor().rejectIdentity();107 try p.clearCofactor().rejectIdentity();
107 const one = std.crypto.ecc.Edwards25519.Fe.one;108 const one = std.crypto.ecc.Edwards25519.Fe.one;
108 const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd)109 const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd)
lib/std/crypto/25519/ed25519.zig+12-11
...@@ -8,7 +8,8 @@ const crypto = std.crypto;...@@ -8,7 +8,8 @@ const crypto = std.crypto;
8const debug = std.debug;8const debug = std.debug;
9const fmt = std.fmt;9const fmt = std.fmt;
10const mem = std.mem;10const mem = std.mem;
11const Sha512 = std.crypto.hash.sha2.Sha512;11const Sha512 = crypto.hash.sha2.Sha512;
12const Error = crypto.Error;
1213
13/// Ed25519 (EdDSA) signatures.14/// Ed25519 (EdDSA) signatures.
14pub const Ed25519 = struct {15pub const Ed25519 = struct {
...@@ -40,7 +41,7 @@ pub const Ed25519 = struct {...@@ -40,7 +41,7 @@ pub const Ed25519 = struct {
40 ///41 ///
41 /// For this reason, an EdDSA secret key is commonly called a seed,42 /// For this reason, an EdDSA secret key is commonly called a seed,
42 /// from which the actual secret is derived.43 /// from which the actual secret is derived.
43 pub fn create(seed: ?[seed_length]u8) !KeyPair {44 pub fn create(seed: ?[seed_length]u8) Error!KeyPair {
44 const ss = seed orelse ss: {45 const ss = seed orelse ss: {
45 var random_seed: [seed_length]u8 = undefined;46 var random_seed: [seed_length]u8 = undefined;
46 crypto.random.bytes(&random_seed);47 crypto.random.bytes(&random_seed);
...@@ -71,7 +72,7 @@ pub const Ed25519 = struct {...@@ -71,7 +72,7 @@ pub const Ed25519 = struct {
71 /// Sign a message using a key pair, and optional random noise.72 /// Sign a message using a key pair, and optional random noise.
72 /// Having noise creates non-standard, non-deterministic signatures,73 /// Having noise creates non-standard, non-deterministic signatures,
73 /// but has been proven to increase resilience against fault attacks.74 /// but has been proven to increase resilience against fault attacks.
74 pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) ![signature_length]u8 {75 pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) Error![signature_length]u8 {
75 const seed = key_pair.secret_key[0..seed_length];76 const seed = key_pair.secret_key[0..seed_length];
76 const public_key = key_pair.secret_key[seed_length..];77 const public_key = key_pair.secret_key[seed_length..];
77 if (!mem.eql(u8, public_key, &key_pair.public_key)) {78 if (!mem.eql(u8, public_key, &key_pair.public_key)) {
...@@ -111,8 +112,8 @@ pub const Ed25519 = struct {...@@ -111,8 +112,8 @@ pub const Ed25519 = struct {
111 }112 }
112113
113 /// Verify an Ed25519 signature given a message and a public key.114 /// Verify an Ed25519 signature given a message and a public key.
114 /// Returns error.InvalidSignature is the signature verification failed.115 /// Returns error.SignatureVerificationFailed is the signature verification failed.
115 pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) !void {116 pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) Error!void {
116 const r = sig[0..32];117 const r = sig[0..32];
117 const s = sig[32..64];118 const s = sig[32..64];
118 try Curve.scalar.rejectNonCanonical(s.*);119 try Curve.scalar.rejectNonCanonical(s.*);
...@@ -133,7 +134,7 @@ pub const Ed25519 = struct {...@@ -133,7 +134,7 @@ pub const Ed25519 = struct {
133 const ah = try a.neg().mulPublic(hram);134 const ah = try a.neg().mulPublic(hram);
134 const sb_ah = (try Curve.basePoint.mulPublic(s.*)).add(ah);135 const sb_ah = (try Curve.basePoint.mulPublic(s.*)).add(ah);
135 if (expected_r.sub(sb_ah).clearCofactor().rejectIdentity()) |_| {136 if (expected_r.sub(sb_ah).clearCofactor().rejectIdentity()) |_| {
136 return error.InvalidSignature;137 return error.SignatureVerificationFailed;
137 } else |_| {}138 } else |_| {}
138 }139 }
139140
...@@ -145,7 +146,7 @@ pub const Ed25519 = struct {...@@ -145,7 +146,7 @@ pub const Ed25519 = struct {
145 };146 };
146147
147 /// Verify several signatures in a single operation, much faster than verifying signatures one-by-one148 /// Verify several signatures in a single operation, much faster than verifying signatures one-by-one
148 pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) !void {149 pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) Error!void {
149 var r_batch: [count][32]u8 = undefined;150 var r_batch: [count][32]u8 = undefined;
150 var s_batch: [count][32]u8 = undefined;151 var s_batch: [count][32]u8 = undefined;
151 var a_batch: [count]Curve = undefined;152 var a_batch: [count]Curve = undefined;
...@@ -200,7 +201,7 @@ pub const Ed25519 = struct {...@@ -200,7 +201,7 @@ pub const Ed25519 = struct {
200201
201 const zsb = try Curve.basePoint.mulPublic(zs_sum);202 const zsb = try Curve.basePoint.mulPublic(zs_sum);
202 if (zr.add(zah).sub(zsb).rejectIdentity()) |_| {203 if (zr.add(zah).sub(zsb).rejectIdentity()) |_| {
203 return error.InvalidSignature;204 return error.SignatureVerificationFailed;
204 } else |_| {}205 } else |_| {}
205 }206 }
206};207};
...@@ -223,7 +224,7 @@ test "ed25519 signature" {...@@ -223,7 +224,7 @@ test "ed25519 signature" {
223 var buf: [128]u8 = undefined;224 var buf: [128]u8 = undefined;
224 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&sig)}), "10A442B4A80CC4225B154F43BEF28D2472CA80221951262EB8E0DF9091575E2687CC486E77263C3418C757522D54F84B0359236ABBBD4ACD20DC297FDCA66808");225 std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{s}", .{std.fmt.fmtSliceHexUpper(&sig)}), "10A442B4A80CC4225B154F43BEF28D2472CA80221951262EB8E0DF9091575E2687CC486E77263C3418C757522D54F84B0359236ABBBD4ACD20DC297FDCA66808");
225 try Ed25519.verify(sig, "test", key_pair.public_key);226 try Ed25519.verify(sig, "test", key_pair.public_key);
226 std.testing.expectError(error.InvalidSignature, Ed25519.verify(sig, "TEST", key_pair.public_key));227 std.testing.expectError(error.SignatureVerificationFailed, Ed25519.verify(sig, "TEST", key_pair.public_key));
227}228}
228229
229test "ed25519 batch verification" {230test "ed25519 batch verification" {
...@@ -251,7 +252,7 @@ test "ed25519 batch verification" {...@@ -251,7 +252,7 @@ test "ed25519 batch verification" {
251 try Ed25519.verifyBatch(2, signature_batch);252 try Ed25519.verifyBatch(2, signature_batch);
252253
253 signature_batch[1].sig = sig1;254 signature_batch[1].sig = sig1;
254 std.testing.expectError(error.InvalidSignature, Ed25519.verifyBatch(signature_batch.len, signature_batch));255 std.testing.expectError(error.SignatureVerificationFailed, Ed25519.verifyBatch(signature_batch.len, signature_batch));
255 }256 }
256}257}
257258
...@@ -316,7 +317,7 @@ test "ed25519 test vectors" {...@@ -316,7 +317,7 @@ test "ed25519 test vectors" {
316 .msg_hex = "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41",317 .msg_hex = "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41",
317 .public_key_hex = "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43",318 .public_key_hex = "f7badec5b8abeaf699583992219b7b223f1df3fbbea919844e3f7c554a43dd43",
318 .sig_hex = "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03be9678ac102edcd92b0210bb34d7428d12ffc5df5f37e359941266a4e35f0f",319 .sig_hex = "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03be9678ac102edcd92b0210bb34d7428d12ffc5df5f37e359941266a4e35f0f",
319 .expected = error.InvalidSignature, // 8 - non-canonical R320 .expected = error.SignatureVerificationFailed, // 8 - non-canonical R
320 },321 },
321 Vec{322 Vec{
322 .msg_hex = "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41",323 .msg_hex = "9bedc267423725d473888631ebf45988bad3db83851ee85c85e241a07d148b41",
lib/std/crypto/25519/edwards25519.zig+11-10
...@@ -7,6 +7,7 @@ const std = @import("std");...@@ -7,6 +7,7 @@ const std = @import("std");
7const debug = std.debug;7const debug = std.debug;
8const fmt = std.fmt;8const fmt = std.fmt;
9const mem = std.mem;9const mem = std.mem;
10const Error = std.crypto.Error;
1011
11/// Group operations over Edwards25519.12/// Group operations over Edwards25519.
12pub const Edwards25519 = struct {13pub const Edwards25519 = struct {
...@@ -25,7 +26,7 @@ pub const Edwards25519 = struct {...@@ -25,7 +26,7 @@ pub const Edwards25519 = struct {
25 is_base: bool = false,26 is_base: bool = false,
2627
27 /// Decode an Edwards25519 point from its compressed (Y+sign) coordinates.28 /// Decode an Edwards25519 point from its compressed (Y+sign) coordinates.
28 pub fn fromBytes(s: [encoded_length]u8) !Edwards25519 {29 pub fn fromBytes(s: [encoded_length]u8) Error!Edwards25519 {
29 const z = Fe.one;30 const z = Fe.one;
30 const y = Fe.fromBytes(s);31 const y = Fe.fromBytes(s);
31 var u = y.sq();32 var u = y.sq();
...@@ -55,7 +56,7 @@ pub const Edwards25519 = struct {...@@ -55,7 +56,7 @@ pub const Edwards25519 = struct {
55 }56 }
5657
57 /// Check that the encoding of a point is canonical.58 /// Check that the encoding of a point is canonical.
58 pub fn rejectNonCanonical(s: [32]u8) !void {59 pub fn rejectNonCanonical(s: [32]u8) Error!void {
59 return Fe.rejectNonCanonical(s, true);60 return Fe.rejectNonCanonical(s, true);
60 }61 }
6162
...@@ -80,7 +81,7 @@ pub const Edwards25519 = struct {...@@ -80,7 +81,7 @@ pub const Edwards25519 = struct {
80 const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };81 const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
8182
82 /// Reject the neutral element.83 /// Reject the neutral element.
83 pub fn rejectIdentity(p: Edwards25519) !void {84 pub fn rejectIdentity(p: Edwards25519) Error!void {
84 if (p.x.isZero()) {85 if (p.x.isZero()) {
85 return error.IdentityElement;86 return error.IdentityElement;
86 }87 }
...@@ -176,7 +177,7 @@ pub const Edwards25519 = struct {...@@ -176,7 +177,7 @@ pub const Edwards25519 = struct {
176 // Based on real-world benchmarks, we only use this for multi-scalar multiplication.177 // Based on real-world benchmarks, we only use this for multi-scalar multiplication.
177 // NAF could be useful to half the size of precomputation tables, but we intentionally178 // NAF could be useful to half the size of precomputation tables, but we intentionally
178 // avoid these to keep the standard library lightweight.179 // avoid these to keep the standard library lightweight.
179 fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) !Edwards25519 {180 fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 {
180 std.debug.assert(vartime);181 std.debug.assert(vartime);
181 const e = nonAdjacentForm(s);182 const e = nonAdjacentForm(s);
182 var q = Edwards25519.identityElement;183 var q = Edwards25519.identityElement;
...@@ -196,7 +197,7 @@ pub const Edwards25519 = struct {...@@ -196,7 +197,7 @@ pub const Edwards25519 = struct {
196 }197 }
197198
198 // Scalar multiplication with a 4-bit window and the first 15 multiples.199 // Scalar multiplication with a 4-bit window and the first 15 multiples.
199 fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) !Edwards25519 {200 fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 {
200 var q = Edwards25519.identityElement;201 var q = Edwards25519.identityElement;
201 var pos: usize = 252;202 var pos: usize = 252;
202 while (true) : (pos -= 4) {203 while (true) : (pos -= 4) {
...@@ -234,7 +235,7 @@ pub const Edwards25519 = struct {...@@ -234,7 +235,7 @@ pub const Edwards25519 = struct {
234 /// Multiply an Edwards25519 point by a scalar without clamping it.235 /// Multiply an Edwards25519 point by a scalar without clamping it.
235 /// Return error.WeakPublicKey if the resulting point is236 /// Return error.WeakPublicKey if the resulting point is
236 /// the identity element.237 /// the identity element.
237 pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {238 pub fn mul(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
238 const pc = if (p.is_base) basePointPc else pc: {239 const pc = if (p.is_base) basePointPc else pc: {
239 const xpc = precompute(p, 15);240 const xpc = precompute(p, 15);
240 xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;241 xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
...@@ -245,7 +246,7 @@ pub const Edwards25519 = struct {...@@ -245,7 +246,7 @@ pub const Edwards25519 = struct {
245246
246 /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*247 /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*
247 /// This can be used for signature verification.248 /// This can be used for signature verification.
248 pub fn mulPublic(p: Edwards25519, s: [32]u8) !Edwards25519 {249 pub fn mulPublic(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
249 if (p.is_base) {250 if (p.is_base) {
250 return pcMul16(basePointPc, s, true);251 return pcMul16(basePointPc, s, true);
251 } else {252 } else {
...@@ -257,7 +258,7 @@ pub const Edwards25519 = struct {...@@ -257,7 +258,7 @@ pub const Edwards25519 = struct {
257258
258 /// Multiscalar multiplication *IN VARIABLE TIME* for public data259 /// Multiscalar multiplication *IN VARIABLE TIME* for public data
259 /// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually260 /// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually
260 pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) !Edwards25519 {261 pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) Error!Edwards25519 {
261 var pcs: [count][9]Edwards25519 = undefined;262 var pcs: [count][9]Edwards25519 = undefined;
262 for (ps) |p, i| {263 for (ps) |p, i| {
263 if (p.is_base) {264 if (p.is_base) {
...@@ -296,14 +297,14 @@ pub const Edwards25519 = struct {...@@ -296,14 +297,14 @@ pub const Edwards25519 = struct {
296 /// This is strongly recommended for DH operations.297 /// This is strongly recommended for DH operations.
297 /// Return error.WeakPublicKey if the resulting point is298 /// Return error.WeakPublicKey if the resulting point is
298 /// the identity element.299 /// the identity element.
299 pub fn clampedMul(p: Edwards25519, s: [32]u8) !Edwards25519 {300 pub fn clampedMul(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
300 var t: [32]u8 = s;301 var t: [32]u8 = s;
301 scalar.clamp(&t);302 scalar.clamp(&t);
302 return mul(p, t);303 return mul(p, t);
303 }304 }
304305
305 // montgomery -- recover y = sqrt(x^3 + A*x^2 + x)306 // montgomery -- recover y = sqrt(x^3 + A*x^2 + x)
306 fn xmontToYmont(x: Fe) !Fe {307 fn xmontToYmont(x: Fe) Error!Fe {
307 var x2 = x.sq();308 var x2 = x.sq();
308 const x3 = x.mul(x2);309 const x3 = x.mul(x2);
309 x2 = x2.mul32(Fe.edwards25519a_32);310 x2 = x2.mul32(Fe.edwards25519a_32);
lib/std/crypto/25519/field.zig+3-2
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6const std = @import("std");6const std = @import("std");
7const readIntLittle = std.mem.readIntLittle;7const readIntLittle = std.mem.readIntLittle;
8const writeIntLittle = std.mem.writeIntLittle;8const writeIntLittle = std.mem.writeIntLittle;
9const Error = std.crypto.Error;
910
10pub const Fe = struct {11pub const Fe = struct {
11 limbs: [5]u64,12 limbs: [5]u64,
...@@ -112,7 +113,7 @@ pub const Fe = struct {...@@ -112,7 +113,7 @@ pub const Fe = struct {
112 }113 }
113114
114 /// Reject non-canonical encodings of an element, possibly ignoring the top bit115 /// Reject non-canonical encodings of an element, possibly ignoring the top bit
115 pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) !void {116 pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) Error!void {
116 var c: u16 = (s[31] & 0x7f) ^ 0x7f;117 var c: u16 = (s[31] & 0x7f) ^ 0x7f;
117 comptime var i = 30;118 comptime var i = 30;
118 inline while (i > 0) : (i -= 1) {119 inline while (i > 0) : (i -= 1) {
...@@ -412,7 +413,7 @@ pub const Fe = struct {...@@ -412,7 +413,7 @@ pub const Fe = struct {
412 }413 }
413414
414 /// Compute the square root of `x2`, returning `error.NotSquare` if `x2` was not a square415 /// Compute the square root of `x2`, returning `error.NotSquare` if `x2` was not a square
415 pub fn sqrt(x2: Fe) !Fe {416 pub fn sqrt(x2: Fe) Error!Fe {
416 var x2_copy = x2;417 var x2_copy = x2;
417 const x = x2.uncheckedSqrt();418 const x = x2.uncheckedSqrt();
418 const check = x.sq().sub(x2_copy);419 const check = x.sq().sub(x2_copy);
lib/std/crypto/25519/ristretto255.zig+5-4
...@@ -5,6 +5,7 @@...@@ -5,6 +5,7 @@
5// and substantial portions of the software.5// and substantial portions of the software.
6const std = @import("std");6const std = @import("std");
7const fmt = std.fmt;7const fmt = std.fmt;
8const Error = std.crypto.Error;
89
9/// Group operations over Edwards25519.10/// Group operations over Edwards25519.
10pub const Ristretto255 = struct {11pub const Ristretto255 = struct {
...@@ -34,7 +35,7 @@ pub const Ristretto255 = struct {...@@ -34,7 +35,7 @@ pub const Ristretto255 = struct {
34 return .{ .ratio_is_square = @boolToInt(has_m_root) | @boolToInt(has_p_root), .root = x.abs() };35 return .{ .ratio_is_square = @boolToInt(has_m_root) | @boolToInt(has_p_root), .root = x.abs() };
35 }36 }
3637
37 fn rejectNonCanonical(s: [encoded_length]u8) !void {38 fn rejectNonCanonical(s: [encoded_length]u8) Error!void {
38 if ((s[0] & 1) != 0) {39 if ((s[0] & 1) != 0) {
39 return error.NonCanonical;40 return error.NonCanonical;
40 }41 }
...@@ -42,7 +43,7 @@ pub const Ristretto255 = struct {...@@ -42,7 +43,7 @@ pub const Ristretto255 = struct {
42 }43 }
4344
44 /// Reject the neutral element.45 /// Reject the neutral element.
45 pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) !void {46 pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) Error!void {
46 return p.p.rejectIdentity();47 return p.p.rejectIdentity();
47 }48 }
4849
...@@ -50,7 +51,7 @@ pub const Ristretto255 = struct {...@@ -50,7 +51,7 @@ pub const Ristretto255 = struct {
50 pub const basePoint = Ristretto255{ .p = Curve.basePoint };51 pub const basePoint = Ristretto255{ .p = Curve.basePoint };
5152
52 /// Decode a Ristretto255 representative.53 /// Decode a Ristretto255 representative.
53 pub fn fromBytes(s: [encoded_length]u8) !Ristretto255 {54 pub fn fromBytes(s: [encoded_length]u8) Error!Ristretto255 {
54 try rejectNonCanonical(s);55 try rejectNonCanonical(s);
55 const s_ = Fe.fromBytes(s);56 const s_ = Fe.fromBytes(s);
56 const ss = s_.sq(); // s^257 const ss = s_.sq(); // s^2
...@@ -153,7 +154,7 @@ pub const Ristretto255 = struct {...@@ -153,7 +154,7 @@ pub const Ristretto255 = struct {
153 /// Multiply a Ristretto255 element with a scalar.154 /// Multiply a Ristretto255 element with a scalar.
154 /// Return error.WeakPublicKey if the resulting element is155 /// Return error.WeakPublicKey if the resulting element is
155 /// the identity element.156 /// the identity element.
156 pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) !Ristretto255 {157 pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) Error!Ristretto255 {
157 return Ristretto255{ .p = try p.p.mul(s) };158 return Ristretto255{ .p = try p.p.mul(s) };
158 }159 }
159160
lib/std/crypto/25519/scalar.zig+2-1
...@@ -5,6 +5,7 @@...@@ -5,6 +5,7 @@
5// and substantial portions of the software.5// and substantial portions of the software.
6const std = @import("std");6const std = @import("std");
7const mem = std.mem;7const mem = std.mem;
8const Error = std.crypto.Error;
89
9/// 2^252 + 2774231777737235353585193779088364849310/// 2^252 + 27742317777372353535851937790883648493
10pub const field_size = [32]u8{11pub const field_size = [32]u8{
...@@ -18,7 +19,7 @@ pub const CompressedScalar = [32]u8;...@@ -18,7 +19,7 @@ pub const CompressedScalar = [32]u8;
18pub const zero = [_]u8{0} ** 32;19pub const zero = [_]u8{0} ** 32;
1920
20/// Reject a scalar whose encoding is not canonical.21/// Reject a scalar whose encoding is not canonical.
21pub fn rejectNonCanonical(s: [32]u8) !void {22pub fn rejectNonCanonical(s: [32]u8) Error!void {
22 var c: u8 = 0;23 var c: u8 = 0;
23 var n: u8 = 1;24 var n: u8 = 1;
24 var i: usize = 31;25 var i: usize = 31;
lib/std/crypto/25519/x25519.zig+6-5
...@@ -9,6 +9,7 @@ const mem = std.mem;...@@ -9,6 +9,7 @@ const mem = std.mem;
9const fmt = std.fmt;9const fmt = std.fmt;
1010
11const Sha512 = crypto.hash.sha2.Sha512;11const Sha512 = crypto.hash.sha2.Sha512;
12const Error = crypto.Error;
1213
13/// X25519 DH function.14/// X25519 DH function.
14pub const X25519 = struct {15pub const X25519 = struct {
...@@ -31,7 +32,7 @@ pub const X25519 = struct {...@@ -31,7 +32,7 @@ pub const X25519 = struct {
31 secret_key: [secret_length]u8,32 secret_key: [secret_length]u8,
3233
33 /// Create a new key pair using an optional seed.34 /// Create a new key pair using an optional seed.
34 pub fn create(seed: ?[seed_length]u8) !KeyPair {35 pub fn create(seed: ?[seed_length]u8) Error!KeyPair {
35 const sk = seed orelse sk: {36 const sk = seed orelse sk: {
36 var random_seed: [seed_length]u8 = undefined;37 var random_seed: [seed_length]u8 = undefined;
37 crypto.random.bytes(&random_seed);38 crypto.random.bytes(&random_seed);
...@@ -44,7 +45,7 @@ pub const X25519 = struct {...@@ -44,7 +45,7 @@ pub const X25519 = struct {
44 }45 }
4546
46 /// Create a key pair from an Ed25519 key pair47 /// Create a key pair from an Ed25519 key pair
47 pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) !KeyPair {48 pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) Error!KeyPair {
48 const seed = ed25519_key_pair.secret_key[0..32];49 const seed = ed25519_key_pair.secret_key[0..32];
49 var az: [Sha512.digest_length]u8 = undefined;50 var az: [Sha512.digest_length]u8 = undefined;
50 Sha512.hash(seed, &az, .{});51 Sha512.hash(seed, &az, .{});
...@@ -59,13 +60,13 @@ pub const X25519 = struct {...@@ -59,13 +60,13 @@ pub const X25519 = struct {
59 };60 };
6061
61 /// Compute the public key for a given private key.62 /// Compute the public key for a given private key.
62 pub fn recoverPublicKey(secret_key: [secret_length]u8) ![public_length]u8 {63 pub fn recoverPublicKey(secret_key: [secret_length]u8) Error![public_length]u8 {
63 const q = try Curve.basePoint.clampedMul(secret_key);64 const q = try Curve.basePoint.clampedMul(secret_key);
64 return q.toBytes();65 return q.toBytes();
65 }66 }
6667
67 /// Compute the X25519 equivalent to an Ed25519 public eky.68 /// Compute the X25519 equivalent to an Ed25519 public eky.
68 pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) ![public_length]u8 {69 pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) Error![public_length]u8 {
69 const pk_ed = try crypto.ecc.Edwards25519.fromBytes(ed25519_public_key);70 const pk_ed = try crypto.ecc.Edwards25519.fromBytes(ed25519_public_key);
70 const pk = try Curve.fromEdwards25519(pk_ed);71 const pk = try Curve.fromEdwards25519(pk_ed);
71 return pk.toBytes();72 return pk.toBytes();
...@@ -74,7 +75,7 @@ pub const X25519 = struct {...@@ -74,7 +75,7 @@ pub const X25519 = struct {
74 /// Compute the scalar product of a public key and a secret scalar.75 /// Compute the scalar product of a public key and a secret scalar.
75 /// Note that the output should not be used as a shared secret without76 /// Note that the output should not be used as a shared secret without
76 /// hashing it first.77 /// hashing it first.
77 pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) ![shared_length]u8 {78 pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) Error![shared_length]u8 {
78 const q = try Curve.fromBytes(public_key).clampedMul(secret_key);79 const q = try Curve.fromBytes(public_key).clampedMul(secret_key);
79 return q.toBytes();80 return q.toBytes();
80 }81 }
lib/std/crypto/aegis.zig+3-2
...@@ -8,6 +8,7 @@ const std = @import("std");...@@ -8,6 +8,7 @@ const std = @import("std");
8const mem = std.mem;8const mem = std.mem;
9const assert = std.debug.assert;9const assert = std.debug.assert;
10const AesBlock = std.crypto.core.aes.Block;10const AesBlock = std.crypto.core.aes.Block;
11const Error = std.crypto.Error;
1112
12const State128L = struct {13const State128L = struct {
13 blocks: [8]AesBlock,14 blocks: [8]AesBlock,
...@@ -136,7 +137,7 @@ pub const Aegis128L = struct {...@@ -136,7 +137,7 @@ pub const Aegis128L = struct {
136 /// ad: Associated Data137 /// ad: Associated Data
137 /// npub: public nonce138 /// npub: public nonce
138 /// k: private key139 /// k: private key
139 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void {140 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) Error!void {
140 assert(c.len == m.len);141 assert(c.len == m.len);
141 var state = State128L.init(key, npub);142 var state = State128L.init(key, npub);
142 var src: [32]u8 align(16) = undefined;143 var src: [32]u8 align(16) = undefined;
...@@ -298,7 +299,7 @@ pub const Aegis256 = struct {...@@ -298,7 +299,7 @@ pub const Aegis256 = struct {
298 /// ad: Associated Data299 /// ad: Associated Data
299 /// npub: public nonce300 /// npub: public nonce
300 /// k: private key301 /// k: private key
301 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void {302 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) Error!void {
302 assert(c.len == m.len);303 assert(c.len == m.len);
303 var state = State256.init(key, npub);304 var state = State256.init(key, npub);
304 var src: [16]u8 align(16) = undefined;305 var src: [16]u8 align(16) = undefined;
lib/std/crypto/aes_gcm.zig+2-1
...@@ -12,6 +12,7 @@ const debug = std.debug;...@@ -12,6 +12,7 @@ const debug = std.debug;
12const Ghash = std.crypto.onetimeauth.Ghash;12const Ghash = std.crypto.onetimeauth.Ghash;
13const mem = std.mem;13const mem = std.mem;
14const modes = crypto.core.modes;14const modes = crypto.core.modes;
15const Error = crypto.Error;
1516
16pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128);17pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128);
17pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256);18pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256);
...@@ -59,7 +60,7 @@ fn AesGcm(comptime Aes: anytype) type {...@@ -59,7 +60,7 @@ fn AesGcm(comptime Aes: anytype) type {
59 }60 }
60 }61 }
6162
62 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void {63 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) Error!void {
63 assert(c.len == m.len);64 assert(c.len == m.len);
6465
65 const aes = Aes.initEnc(key);66 const aes = Aes.initEnc(key);
lib/std/crypto/aes_ocb.zig+2-1
...@@ -10,6 +10,7 @@ const aes = crypto.core.aes;...@@ -10,6 +10,7 @@ const aes = crypto.core.aes;
10const assert = std.debug.assert;10const assert = std.debug.assert;
11const math = std.math;11const math = std.math;
12const mem = std.mem;12const mem = std.mem;
13const Error = crypto.Error;
1314
14pub const Aes128Ocb = AesOcb(aes.Aes128);15pub const Aes128Ocb = AesOcb(aes.Aes128);
15pub const Aes256Ocb = AesOcb(aes.Aes256);16pub const Aes256Ocb = AesOcb(aes.Aes256);
...@@ -178,7 +179,7 @@ fn AesOcb(comptime Aes: anytype) type {...@@ -178,7 +179,7 @@ fn AesOcb(comptime Aes: anytype) type {
178 /// ad: Associated Data179 /// ad: Associated Data
179 /// npub: public nonce180 /// npub: public nonce
180 /// k: secret key181 /// k: secret key
181 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void {182 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) Error!void {
182 assert(c.len == m.len);183 assert(c.len == m.len);
183184
184 const aes_enc_ctx = Aes.initEnc(key);185 const aes_enc_ctx = Aes.initEnc(key);
lib/std/crypto/bcrypt.zig+8-14
...@@ -11,7 +11,8 @@ const math = std.math;...@@ -11,7 +11,8 @@ const math = std.math;
11const mem = std.mem;11const mem = std.mem;
12const debug = std.debug;12const debug = std.debug;
13const testing = std.testing;13const testing = std.testing;
14const utils = std.crypto.utils;14const utils = crypto.utils;
15const Error = crypto.Error;
1516
16const salt_length: usize = 16;17const salt_length: usize = 16;
17const salt_str_length: usize = 22;18const salt_str_length: usize = 22;
...@@ -21,13 +22,6 @@ const ct_length: usize = 24;...@@ -21,13 +22,6 @@ const ct_length: usize = 24;
21/// Length (in bytes) of a password hash22/// Length (in bytes) of a password hash
22pub const hash_length: usize = 60;23pub const hash_length: usize = 60;
2324
24pub const BcryptError = error{
25 /// The hashed password cannot be decoded.
26 InvalidEncoding,
27 /// The hash is not valid for the given password.
28 InvalidPassword,
29};
30
31const State = struct {25const State = struct {
32 sboxes: [4][256]u32 = [4][256]u32{26 sboxes: [4][256]u32 = [4][256]u32{
33 .{ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a },27 .{ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a },
...@@ -185,7 +179,7 @@ const Codec = struct {...@@ -185,7 +179,7 @@ const Codec = struct {
185 debug.assert(j == b64.len);179 debug.assert(j == b64.len);
186 }180 }
187181
188 fn decode(bin: []u8, b64: []const u8) BcryptError!void {182 fn decode(bin: []u8, b64: []const u8) Error!void {
189 var i: usize = 0;183 var i: usize = 0;
190 var j: usize = 0;184 var j: usize = 0;
191 while (j < bin.len) {185 while (j < bin.len) {
...@@ -210,7 +204,7 @@ const Codec = struct {...@@ -210,7 +204,7 @@ const Codec = struct {
210 }204 }
211};205};
212206
213fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) BcryptError![hash_length]u8 {207fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) Error![hash_length]u8 {
214 var state = State{};208 var state = State{};
215 var password_buf: [73]u8 = undefined;209 var password_buf: [73]u8 = undefined;
216 const trimmed_len = math.min(password.len, password_buf.len - 1);210 const trimmed_len = math.min(password.len, password_buf.len - 1);
...@@ -258,14 +252,14 @@ fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8)...@@ -258,14 +252,14 @@ fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8)
258/// IMPORTANT: by design, bcrypt silently truncates passwords to 72 bytes.252/// IMPORTANT: by design, bcrypt silently truncates passwords to 72 bytes.
259/// If this is an issue for your application, hash the password first using a function such as SHA-512,253/// If this is an issue for your application, hash the password first using a function such as SHA-512,
260/// and then use the resulting hash as the password parameter for bcrypt.254/// and then use the resulting hash as the password parameter for bcrypt.
261pub fn strHash(password: []const u8, rounds_log: u6) ![hash_length]u8 {255pub fn strHash(password: []const u8, rounds_log: u6) Error![hash_length]u8 {
262 var salt: [salt_length]u8 = undefined;256 var salt: [salt_length]u8 = undefined;
263 crypto.random.bytes(&salt);257 crypto.random.bytes(&salt);
264 return strHashInternal(password, rounds_log, salt);258 return strHashInternal(password, rounds_log, salt);
265}259}
266260
267/// Verify that a previously computed hash is valid for a given password.261/// Verify that a previously computed hash is valid for a given password.
268pub fn strVerify(h: [hash_length]u8, password: []const u8) BcryptError!void {262pub fn strVerify(h: [hash_length]u8, password: []const u8) Error!void {
269 if (!mem.eql(u8, "$2", h[0..2])) return error.InvalidEncoding;263 if (!mem.eql(u8, "$2", h[0..2])) return error.InvalidEncoding;
270 if (h[3] != '$' or h[6] != '$') return error.InvalidEncoding;264 if (h[3] != '$' or h[6] != '$') return error.InvalidEncoding;
271 const rounds_log_str = h[4..][0..2];265 const rounds_log_str = h[4..][0..2];
...@@ -275,7 +269,7 @@ pub fn strVerify(h: [hash_length]u8, password: []const u8) BcryptError!void {...@@ -275,7 +269,7 @@ pub fn strVerify(h: [hash_length]u8, password: []const u8) BcryptError!void {
275 const rounds_log = fmt.parseInt(u6, rounds_log_str[0..], 10) catch return error.InvalidEncoding;269 const rounds_log = fmt.parseInt(u6, rounds_log_str[0..], 10) catch return error.InvalidEncoding;
276 const wanted_s = try strHashInternal(password, rounds_log, salt);270 const wanted_s = try strHashInternal(password, rounds_log, salt);
277 if (!mem.eql(u8, wanted_s[0..], h[0..])) {271 if (!mem.eql(u8, wanted_s[0..], h[0..])) {
278 return error.InvalidPassword;272 return error.PasswordVerificationFailed;
279 }273 }
280}274}
281275
...@@ -292,7 +286,7 @@ test "bcrypt codec" {...@@ -292,7 +286,7 @@ test "bcrypt codec" {
292test "bcrypt" {286test "bcrypt" {
293 const s = try strHash("password", 5);287 const s = try strHash("password", 5);
294 try strVerify(s, "password");288 try strVerify(s, "password");
295 testing.expectError(error.InvalidPassword, strVerify(s, "invalid password"));289 testing.expectError(error.PasswordVerificationFailed, strVerify(s, "invalid password"));
296290
297 const long_s = try strHash("password" ** 100, 5);291 const long_s = try strHash("password" ** 100, 5);
298 try strVerify(long_s, "password" ** 100);292 try strVerify(long_s, "password" ** 100);
lib/std/crypto/chacha20.zig+9-8
...@@ -13,6 +13,7 @@ const testing = std.testing;...@@ -13,6 +13,7 @@ const testing = std.testing;
13const maxInt = math.maxInt;13const maxInt = math.maxInt;
14const Vector = std.meta.Vector;14const Vector = std.meta.Vector;
15const Poly1305 = std.crypto.onetimeauth.Poly1305;15const Poly1305 = std.crypto.onetimeauth.Poly1305;
16const Error = std.crypto.Error;
1617
17// Vectorized implementation of the core function18// Vectorized implementation of the core function
18const ChaCha20VecImpl = struct {19const ChaCha20VecImpl = struct {
...@@ -656,7 +657,7 @@ fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []c...@@ -656,7 +657,7 @@ fn chacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []c
656}657}
657658
658/// Verifies and decrypts an authenticated message produced by chacha20poly1305SealDetached.659/// Verifies and decrypts an authenticated message produced by chacha20poly1305SealDetached.
659fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void {660fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [12]u8) Error!void {
660 // split ciphertext and tag661 // split ciphertext and tag
661 assert(dst.len == ciphertext.len);662 assert(dst.len == ciphertext.len);
662663
...@@ -702,9 +703,9 @@ fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [...@@ -702,9 +703,9 @@ fn chacha20poly1305OpenDetached(dst: []u8, ciphertext: []const u8, tag: *const [
702}703}
703704
704/// Verifies and decrypts an authenticated message produced by chacha20poly1305Seal.705/// Verifies and decrypts an authenticated message produced by chacha20poly1305Seal.
705fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) !void {706fn chacha20poly1305Open(dst: []u8, ciphertextAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [12]u8) Error!void {
706 if (ciphertextAndTag.len < chacha20poly1305_tag_length) {707 if (ciphertextAndTag.len < chacha20poly1305_tag_length) {
707 return error.InvalidMessage;708 return error.AuthenticationFailed;
708 }709 }
709 const ciphertextLen = ciphertextAndTag.len - chacha20poly1305_tag_length;710 const ciphertextLen = ciphertextAndTag.len - chacha20poly1305_tag_length;
710 return try chacha20poly1305OpenDetached(dst, ciphertextAndTag[0..ciphertextLen], ciphertextAndTag[ciphertextLen..][0..chacha20poly1305_tag_length], data, key, nonce);711 return try chacha20poly1305OpenDetached(dst, ciphertextAndTag[0..ciphertextLen], ciphertextAndTag[ciphertextLen..][0..chacha20poly1305_tag_length], data, key, nonce);
...@@ -740,13 +741,13 @@ fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []...@@ -740,13 +741,13 @@ fn xchacha20poly1305Seal(ciphertextAndTag: []u8, plaintext: []const u8, data: []
740}741}
741742
742/// Verifies and decrypts an authenticated message produced by xchacha20poly1305SealDetached.743/// Verifies and decrypts an authenticated message produced by xchacha20poly1305SealDetached.
743fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void {744fn xchacha20poly1305OpenDetached(plaintext: []u8, ciphertext: []const u8, tag: *const [chacha20poly1305_tag_length]u8, data: []const u8, key: [32]u8, nonce: [24]u8) Error!void {
744 const extended = extend(key, nonce);745 const extended = extend(key, nonce);
745 return try chacha20poly1305OpenDetached(plaintext, ciphertext, tag, data, extended.key, extended.nonce);746 return try chacha20poly1305OpenDetached(plaintext, ciphertext, tag, data, extended.key, extended.nonce);
746}747}
747748
748/// Verifies and decrypts an authenticated message produced by xchacha20poly1305Seal.749/// Verifies and decrypts an authenticated message produced by xchacha20poly1305Seal.
749fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) !void {750fn xchacha20poly1305Open(ciphertextAndTag: []u8, msgAndTag: []const u8, data: []const u8, key: [32]u8, nonce: [24]u8) Error!void {
750 const extended = extend(key, nonce);751 const extended = extend(key, nonce);
751 return try chacha20poly1305Open(ciphertextAndTag, msgAndTag, data, extended.key, extended.nonce);752 return try chacha20poly1305Open(ciphertextAndTag, msgAndTag, data, extended.key, extended.nonce);
752}753}
...@@ -864,7 +865,7 @@ test "open" {...@@ -864,7 +865,7 @@ test "open" {
864 testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], ciphertext[0..], data[0..], key, bad_nonce));865 testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], ciphertext[0..], data[0..], key, bad_nonce));
865866
866 // a short ciphertext should result in a different error867 // a short ciphertext should result in a different error
867 testing.expectError(error.InvalidMessage, chacha20poly1305Open(out[0..], "", data[0..], key, bad_nonce));868 testing.expectError(error.AuthenticationFailed, chacha20poly1305Open(out[0..], "", data[0..], key, bad_nonce));
868 }869 }
869}870}
870871
...@@ -915,7 +916,7 @@ pub const Chacha20Poly1305 = struct {...@@ -915,7 +916,7 @@ pub const Chacha20Poly1305 = struct {
915 /// npub: public nonce916 /// npub: public nonce
916 /// k: private key917 /// k: private key
917 /// NOTE: the check of the authentication tag is currently not done in constant time918 /// NOTE: the check of the authentication tag is currently not done in constant time
918 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void {919 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
919 assert(c.len == m.len);920 assert(c.len == m.len);
920 return try chacha20poly1305OpenDetached(m, c, tag[0..], ad, k, npub);921 return try chacha20poly1305OpenDetached(m, c, tag[0..], ad, k, npub);
921 }922 }
...@@ -944,7 +945,7 @@ pub const XChacha20Poly1305 = struct {...@@ -944,7 +945,7 @@ pub const XChacha20Poly1305 = struct {
944 /// npub: public nonce945 /// npub: public nonce
945 /// k: private key946 /// k: private key
946 /// NOTE: the check of the authentication tag is currently not done in constant time947 /// NOTE: the check of the authentication tag is currently not done in constant time
947 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void {948 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
948 assert(c.len == m.len);949 assert(c.len == m.len);
949 return try xchacha20poly1305OpenDetached(m, c, tag[0..], ad, k, npub);950 return try xchacha20poly1305OpenDetached(m, c, tag[0..], ad, k, npub);
950 }951 }
lib/std/crypto/error.zig created+34
...@@ -0,0 +1,34 @@
1pub const Error = error{
2 /// MAC verification failed - The tag doesn't verify for the given ciphertext and secret key
3 AuthenticationFailed,
4
5 /// The requested output length is too long for the chosen algorithm
6 OutputTooLong,
7
8 /// Finite field operation returned the identity element
9 IdentityElement,
10
11 /// Encoded input cannot be decoded
12 InvalidEncoding,
13
14 /// The signature does't verify for the given message and public key
15 SignatureVerificationFailed,
16
17 /// Both a public and secret key have been provided, but they are incompatible
18 KeyMismatch,
19
20 /// Encoded input is not in canonical form
21 NonCanonical,
22
23 /// Square root has no solutions
24 NotSquare,
25
26 /// Verification string doesn't match the provided password and parameters
27 PasswordVerificationFailed,
28
29 /// Parameters would be insecure to use
30 WeakParameters,
31
32 /// Public key would be insecure to use
33 WeakPublicKey,
34};
lib/std/crypto/gimli.zig+3-2
...@@ -20,6 +20,7 @@ const assert = std.debug.assert;...@@ -20,6 +20,7 @@ const assert = std.debug.assert;
20const testing = std.testing;20const testing = std.testing;
21const htest = @import("test.zig");21const htest = @import("test.zig");
22const Vector = std.meta.Vector;22const Vector = std.meta.Vector;
23const Error = std.crypto.Error;
2324
24pub const State = struct {25pub const State = struct {
25 pub const BLOCKBYTES = 48;26 pub const BLOCKBYTES = 48;
...@@ -392,7 +393,7 @@ pub const Aead = struct {...@@ -392,7 +393,7 @@ pub const Aead = struct {
392 /// npub: public nonce393 /// npub: public nonce
393 /// k: private key394 /// k: private key
394 /// NOTE: the check of the authentication tag is currently not done in constant time395 /// NOTE: the check of the authentication tag is currently not done in constant time
395 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void {396 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
396 assert(c.len == m.len);397 assert(c.len == m.len);
397398
398 var state = Aead.init(ad, npub, k);399 var state = Aead.init(ad, npub, k);
...@@ -429,7 +430,7 @@ pub const Aead = struct {...@@ -429,7 +430,7 @@ pub const Aead = struct {
429 // TODO: use a constant-time equality check here, see https://github.com/ziglang/zig/issues/1776430 // TODO: use a constant-time equality check here, see https://github.com/ziglang/zig/issues/1776
430 if (!mem.eql(u8, buf[0..State.RATE], &tag)) {431 if (!mem.eql(u8, buf[0..State.RATE], &tag)) {
431 @memset(m.ptr, undefined, m.len);432 @memset(m.ptr, undefined, m.len);
432 return error.InvalidMessage;433 return error.AuthenticationFailed;
433 }434 }
434 }435 }
435};436};
lib/std/crypto/isap.zig+2-1
...@@ -3,6 +3,7 @@ const debug = std.debug;...@@ -3,6 +3,7 @@ const debug = std.debug;
3const mem = std.mem;3const mem = std.mem;
4const math = std.math;4const math = std.math;
5const testing = std.testing;5const testing = std.testing;
6const Error = std.crypto.Error;
67
7/// ISAPv2 is an authenticated encryption system hardened against side channels and fault attacks.8/// ISAPv2 is an authenticated encryption system hardened against side channels and fault attacks.
8/// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-2/spec-doc-rnd2/isap-spec-round2.pdf9/// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-2/spec-doc-rnd2/isap-spec-round2.pdf
...@@ -217,7 +218,7 @@ pub const IsapA128A = struct {...@@ -217,7 +218,7 @@ pub const IsapA128A = struct {
217 tag.* = mac(c, ad, npub, key);218 tag.* = mac(c, ad, npub, key);
218 }219 }
219220
220 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) !void {221 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) Error!void {
221 var computed_tag = mac(c, ad, npub, key);222 var computed_tag = mac(c, ad, npub, key);
222 var acc: u8 = 0;223 var acc: u8 = 0;
223 for (computed_tag) |_, j| {224 for (computed_tag) |_, j| {
lib/std/crypto/pbkdf2.zig+4-11
...@@ -7,6 +7,7 @@...@@ -7,6 +7,7 @@
7const std = @import("std");7const std = @import("std");
8const mem = std.mem;8const mem = std.mem;
9const maxInt = std.math.maxInt;9const maxInt = std.math.maxInt;
10const Error = std.crypto.Error;
1011
11// RFC 2898 Section 5.212// RFC 2898 Section 5.2
12//13//
...@@ -36,14 +37,6 @@ const maxInt = std.math.maxInt;...@@ -36,14 +37,6 @@ const maxInt = std.math.maxInt;
3637
37// Based on Apple's CommonKeyDerivation, based originally on code by Damien Bergamini.38// Based on Apple's CommonKeyDerivation, based originally on code by Damien Bergamini.
3839
39pub const Pbkdf2Error = error{
40 /// At least one round is required
41 TooFewRounds,
42
43 /// Maximum length of the derived key is `maxInt(u32) * Prf.mac_length`
44 DerivedKeyTooLong,
45};
46
47/// Apply PBKDF2 to generate a key from a password.40/// Apply PBKDF2 to generate a key from a password.
48///41///
49/// PBKDF2 is defined in RFC 2898, and is a recommendation of NIST SP 800-132.42/// PBKDF2 is defined in RFC 2898, and is a recommendation of NIST SP 800-132.
...@@ -62,8 +55,8 @@ pub const Pbkdf2Error = error{...@@ -62,8 +55,8 @@ pub const Pbkdf2Error = error{
62/// the derivedKey. It is common to tune this parameter to achieve approximately 100ms.55/// the derivedKey. It is common to tune this parameter to achieve approximately 100ms.
63///56///
64/// Prf: Pseudo-random function to use. A common choice is `std.crypto.auth.hmac.HmacSha256`.57/// Prf: Pseudo-random function to use. A common choice is `std.crypto.auth.hmac.HmacSha256`.
65pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) Pbkdf2Error!void {58pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) Error!void {
66 if (rounds < 1) return error.TooFewRounds;59 if (rounds < 1) return error.WeakParameters;
6760
68 const dkLen = derivedKey.len;61 const dkLen = derivedKey.len;
69 const hLen = Prf.mac_length;62 const hLen = Prf.mac_length;
...@@ -76,7 +69,7 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:...@@ -76,7 +69,7 @@ pub fn pbkdf2(derivedKey: []u8, password: []const u8, salt: []const u8, rounds:
76 //69 //
77 if (comptime (maxInt(usize) > maxInt(u32) * hLen) and (dkLen > @as(usize, maxInt(u32) * hLen))) {70 if (comptime (maxInt(usize) > maxInt(u32) * hLen) and (dkLen > @as(usize, maxInt(u32) * hLen))) {
78 // If maxInt(usize) is less than `maxInt(u32) * hLen` then dkLen is always inbounds71 // If maxInt(usize) is less than `maxInt(u32) * hLen` then dkLen is always inbounds
79 return error.DerivedKeyTooLong;72 return error.OutputTooLong;
80 }73 }
8174
82 // FromSpec:75 // FromSpec:
lib/std/crypto/salsa20.zig+8-7
...@@ -15,6 +15,7 @@ const Vector = std.meta.Vector;...@@ -15,6 +15,7 @@ const Vector = std.meta.Vector;
15const Poly1305 = crypto.onetimeauth.Poly1305;15const Poly1305 = crypto.onetimeauth.Poly1305;
16const Blake2b = crypto.hash.blake2.Blake2b;16const Blake2b = crypto.hash.blake2.Blake2b;
17const X25519 = crypto.dh.X25519;17const X25519 = crypto.dh.X25519;
18const Error = crypto.Error;
1819
19const Salsa20VecImpl = struct {20const Salsa20VecImpl = struct {
20 const Lane = Vector(4, u32);21 const Lane = Vector(4, u32);
...@@ -398,7 +399,7 @@ pub const XSalsa20Poly1305 = struct {...@@ -398,7 +399,7 @@ pub const XSalsa20Poly1305 = struct {
398 /// ad: Associated Data399 /// ad: Associated Data
399 /// npub: public nonce400 /// npub: public nonce
400 /// k: private key401 /// k: private key
401 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void {402 pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
402 debug.assert(c.len == m.len);403 debug.assert(c.len == m.len);
403 const extended = extend(k, npub);404 const extended = extend(k, npub);
404 var block0 = [_]u8{0} ** 64;405 var block0 = [_]u8{0} ** 64;
...@@ -446,7 +447,7 @@ pub const SecretBox = struct {...@@ -446,7 +447,7 @@ pub const SecretBox = struct {
446447
447 /// Verify and decrypt `c` using a nonce `npub` and a key `k`.448 /// Verify and decrypt `c` using a nonce `npub` and a key `k`.
448 /// `m` must be exactly `tag_length` smaller than `c`, as `c` includes an authentication tag in addition to the encrypted message.449 /// `m` must be exactly `tag_length` smaller than `c`, as `c` includes an authentication tag in addition to the encrypted message.
449 pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) !void {450 pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
450 if (c.len < tag_length) {451 if (c.len < tag_length) {
451 return error.AuthenticationFailed;452 return error.AuthenticationFailed;
452 }453 }
...@@ -481,20 +482,20 @@ pub const Box = struct {...@@ -481,20 +482,20 @@ pub const Box = struct {
481 pub const KeyPair = X25519.KeyPair;482 pub const KeyPair = X25519.KeyPair;
482483
483 /// Compute a secret suitable for `secretbox` given a recipent's public key and a sender's secret key.484 /// Compute a secret suitable for `secretbox` given a recipent's public key and a sender's secret key.
484 pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) ![shared_length]u8 {485 pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) Error![shared_length]u8 {
485 const p = try X25519.scalarmult(secret_key, public_key);486 const p = try X25519.scalarmult(secret_key, public_key);
486 const zero = [_]u8{0} ** 16;487 const zero = [_]u8{0} ** 16;
487 return Salsa20Impl.hsalsa20(zero, p);488 return Salsa20Impl.hsalsa20(zero, p);
488 }489 }
489490
490 /// Encrypt and authenticate a message using a recipient's public key `public_key` and a sender's `secret_key`.491 /// Encrypt and authenticate a message using a recipient's public key `public_key` and a sender's `secret_key`.
491 pub fn seal(c: []u8, m: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) !void {492 pub fn seal(c: []u8, m: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) Error!void {
492 const shared_key = try createSharedSecret(public_key, secret_key);493 const shared_key = try createSharedSecret(public_key, secret_key);
493 return SecretBox.seal(c, m, npub, shared_key);494 return SecretBox.seal(c, m, npub, shared_key);
494 }495 }
495496
496 /// Verify and decrypt a message using a recipient's secret key `public_key` and a sender's `public_key`.497 /// Verify and decrypt a message using a recipient's secret key `public_key` and a sender's `public_key`.
497 pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) !void {498 pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) Error!void {
498 const shared_key = try createSharedSecret(public_key, secret_key);499 const shared_key = try createSharedSecret(public_key, secret_key);
499 return SecretBox.open(m, c, npub, shared_key);500 return SecretBox.open(m, c, npub, shared_key);
500 }501 }
...@@ -527,7 +528,7 @@ pub const SealedBox = struct {...@@ -527,7 +528,7 @@ pub const SealedBox = struct {
527528
528 /// Encrypt a message `m` for a recipient whose public key is `public_key`.529 /// Encrypt a message `m` for a recipient whose public key is `public_key`.
529 /// `c` must be `seal_length` bytes larger than `m`, so that the required metadata can be added.530 /// `c` must be `seal_length` bytes larger than `m`, so that the required metadata can be added.
530 pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) !void {531 pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) Error!void {
531 debug.assert(c.len == m.len + seal_length);532 debug.assert(c.len == m.len + seal_length);
532 var ekp = try KeyPair.create(null);533 var ekp = try KeyPair.create(null);
533 const nonce = createNonce(ekp.public_key, public_key);534 const nonce = createNonce(ekp.public_key, public_key);
...@@ -538,7 +539,7 @@ pub const SealedBox = struct {...@@ -538,7 +539,7 @@ pub const SealedBox = struct {
538539
539 /// Decrypt a message using a key pair.540 /// Decrypt a message using a key pair.
540 /// `m` must be exactly `seal_length` bytes smaller than `c`, as `c` also includes metadata.541 /// `m` must be exactly `seal_length` bytes smaller than `c`, as `c` also includes metadata.
541 pub fn open(m: []u8, c: []const u8, keypair: KeyPair) !void {542 pub fn open(m: []u8, c: []const u8, keypair: KeyPair) Error!void {
542 if (c.len < seal_length) {543 if (c.len < seal_length) {
543 return error.AuthenticationFailed;544 return error.AuthenticationFailed;
544 }545 }