| author | |
| committer | |
| log | 10f2d6278946485f057f65bbb3c094a6fcde1adf |
| tree | d7e4f5182e5fd226a705fb3bfbab9d35faa1e1ef |
| parent | 1e06a74348d11e4eef456a067dc5065c1e8b1ee9 |
| signature |
std/crypto: use finer-grained error sets in function signatures
Returning the `crypto.Error` error set for all crypto operations
was very convenient to ensure that errors were used consistently,
and to avoid having multiple error names for the same thing.
The flipside is that callers were forced to always handle all
possible errors, even those that could never be returned by a
function.
This PR makes all functions return union sets of the actual errors
they can return.
The error sets themselves are all limited to a single error.
Larger sets are useful for platform-specific APIs, but we don't have
any of these in `std/crypto`, and I couldn't find any meaningful way
to build larger sets.
19 files changed, 148 insertions(+), 114 deletions(-)
lib/std/crypto.zig+1-1| ... | @@ -154,7 +154,7 @@ pub const random = &@import("crypto/tlcsprng.zig").interface; | ... | @@ -154,7 +154,7 @@ pub const random = &@import("crypto/tlcsprng.zig").interface; |
| 154 | 154 | ||
| 155 | const std = @import("std.zig"); | 155 | const std = @import("std.zig"); |
| 156 | 156 | ||
| 157 | pub const Error = @import("crypto/error.zig").Error; | 157 | pub const errors = @import("crypto/errors.zig"); |
| 158 | 158 | ||
| 159 | test "crypto" { | 159 | test "crypto" { |
| 160 | const please_windows_dont_oom = std.Target.current.os.tag == .windows; | 160 | const please_windows_dont_oom = std.Target.current.os.tag == .windows; |
lib/std/crypto/25519/curve25519.zig+12-8| ... | @@ -4,7 +4,11 @@ | ... | @@ -4,7 +4,11 @@ |
| 4 | // The MIT license requires this copyright notice to be included in all copies | 4 | // 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. |
| 6 | const std = @import("std"); | 6 | const std = @import("std"); |
| 7 | const Error = std.crypto.Error; | 7 | const crypto = std.crypto; |
| 8 | |||
| 9 | const IdentityElementError = crypto.errors.IdentityElementError; | ||
| 10 | const NonCanonicalError = crypto.errors.NonCanonicalError; | ||
| 11 | const WeakPublicKeyError = crypto.errors.WeakPublicKeyError; | ||
| 8 | 12 | ||
| 9 | /// Group operations over Curve25519. | 13 | /// Group operations over Curve25519. |
| 10 | pub const Curve25519 = struct { | 14 | pub const Curve25519 = struct { |
| ... | @@ -29,12 +33,12 @@ pub const Curve25519 = struct { | ... | @@ -29,12 +33,12 @@ pub const Curve25519 = struct { |
| 29 | pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint }; | 33 | pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint }; |
| 30 | 34 | ||
| 31 | /// Check that the encoding of a Curve25519 point is canonical. | 35 | /// Check that the encoding of a Curve25519 point is canonical. |
| 32 | pub fn rejectNonCanonical(s: [32]u8) Error!void { | 36 | pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void { |
| 33 | return Fe.rejectNonCanonical(s, false); | 37 | return Fe.rejectNonCanonical(s, false); |
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | /// Reject the neutral element. | 40 | /// Reject the neutral element. |
| 37 | pub fn rejectIdentity(p: Curve25519) Error!void { | 41 | pub fn rejectIdentity(p: Curve25519) IdentityElementError!void { |
| 38 | if (p.x.isZero()) { | 42 | if (p.x.isZero()) { |
| 39 | return error.IdentityElement; | 43 | return error.IdentityElement; |
| 40 | } | 44 | } |
| ... | @@ -45,7 +49,7 @@ pub const Curve25519 = struct { | ... | @@ -45,7 +49,7 @@ pub const Curve25519 = struct { |
| 45 | return p.dbl().dbl().dbl(); | 49 | return p.dbl().dbl().dbl(); |
| 46 | } | 50 | } |
| 47 | 51 | ||
| 48 | fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) Error!Curve25519 { | 52 | fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) IdentityElementError!Curve25519 { |
| 49 | var x1 = p.x; | 53 | var x1 = p.x; |
| 50 | var x2 = Fe.one; | 54 | var x2 = Fe.one; |
| 51 | var z2 = Fe.zero; | 55 | var z2 = Fe.zero; |
| ... | @@ -86,7 +90,7 @@ pub const Curve25519 = struct { | ... | @@ -86,7 +90,7 @@ pub const Curve25519 = struct { |
| 86 | /// way to use Curve25519 for a DH operation. | 90 | /// way to use Curve25519 for a DH operation. |
| 87 | /// Return error.IdentityElement if the resulting point is | 91 | /// Return error.IdentityElement if the resulting point is |
| 88 | /// the identity element. | 92 | /// the identity element. |
| 89 | pub fn clampedMul(p: Curve25519, s: [32]u8) Error!Curve25519 { | 93 | pub fn clampedMul(p: Curve25519, s: [32]u8) IdentityElementError!Curve25519 { |
| 90 | var t: [32]u8 = s; | 94 | var t: [32]u8 = s; |
| 91 | scalar.clamp(&t); | 95 | scalar.clamp(&t); |
| 92 | return try ladder(p, t, 255); | 96 | return try ladder(p, t, 255); |
| ... | @@ -96,16 +100,16 @@ pub const Curve25519 = struct { | ... | @@ -96,16 +100,16 @@ pub const Curve25519 = struct { |
| 96 | /// Return error.IdentityElement if the resulting point is | 100 | /// Return error.IdentityElement if the resulting point is |
| 97 | /// the identity element or error.WeakPublicKey if the public | 101 | /// the identity element or error.WeakPublicKey if the public |
| 98 | /// key is a low-order point. | 102 | /// key is a low-order point. |
| 99 | pub fn mul(p: Curve25519, s: [32]u8) Error!Curve25519 { | 103 | pub fn mul(p: Curve25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Curve25519 { |
| 100 | const cofactor = [_]u8{8} ++ [_]u8{0} ** 31; | 104 | const cofactor = [_]u8{8} ++ [_]u8{0} ** 31; |
| 101 | _ = ladder(p, cofactor, 4) catch |_| return error.WeakPublicKey; | 105 | _ = ladder(p, cofactor, 4) catch |_| return error.WeakPublicKey; |
| 102 | return try ladder(p, s, 256); | 106 | return try ladder(p, s, 256); |
| 103 | } | 107 | } |
| 104 | 108 | ||
| 105 | /// Compute the Curve25519 equivalent to an Edwards25519 point. | 109 | /// Compute the Curve25519 equivalent to an Edwards25519 point. |
| 106 | pub fn fromEdwards25519(p: std.crypto.ecc.Edwards25519) Error!Curve25519 { | 110 | pub fn fromEdwards25519(p: crypto.ecc.Edwards25519) IdentityElementError!Curve25519 { |
| 107 | try p.clearCofactor().rejectIdentity(); | 111 | try p.clearCofactor().rejectIdentity(); |
| 108 | const one = std.crypto.ecc.Edwards25519.Fe.one; | 112 | const one = crypto.ecc.Edwards25519.Fe.one; |
| 109 | const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd) | 113 | const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd) |
| 110 | return Curve25519{ .x = x }; | 114 | return Curve25519{ .x = x }; |
| 111 | } | 115 | } |
lib/std/crypto/25519/ed25519.zig+16-9| ... | @@ -8,8 +8,15 @@ const crypto = std.crypto; | ... | @@ -8,8 +8,15 @@ const crypto = std.crypto; |
| 8 | const debug = std.debug; | 8 | const debug = std.debug; |
| 9 | const fmt = std.fmt; | 9 | const fmt = std.fmt; |
| 10 | const mem = std.mem; | 10 | const mem = std.mem; |
| 11 | |||
| 11 | const Sha512 = crypto.hash.sha2.Sha512; | 12 | const Sha512 = crypto.hash.sha2.Sha512; |
| 12 | const Error = crypto.Error; | 13 | |
| 14 | const EncodingError = crypto.errors.EncodingError; | ||
| 15 | const IdentityElementError = crypto.errors.IdentityElementError; | ||
| 16 | const NonCanonicalError = crypto.errors.NonCanonicalError; | ||
| 17 | const SignatureVerificationError = crypto.errors.SignatureVerificationError; | ||
| 18 | const KeyMismatchError = crypto.errors.KeyMismatchError; | ||
| 19 | const WeakPublicKeyError = crypto.errors.WeakPublicKeyError; | ||
| 13 | 20 | ||
| 14 | /// Ed25519 (EdDSA) signatures. | 21 | /// Ed25519 (EdDSA) signatures. |
| 15 | pub const Ed25519 = struct { | 22 | pub const Ed25519 = struct { |
| ... | @@ -41,7 +48,7 @@ pub const Ed25519 = struct { | ... | @@ -41,7 +48,7 @@ pub const Ed25519 = struct { |
| 41 | /// | 48 | /// |
| 42 | /// For this reason, an EdDSA secret key is commonly called a seed, | 49 | /// For this reason, an EdDSA secret key is commonly called a seed, |
| 43 | /// from which the actual secret is derived. | 50 | /// from which the actual secret is derived. |
| 44 | pub fn create(seed: ?[seed_length]u8) Error!KeyPair { | 51 | pub fn create(seed: ?[seed_length]u8) IdentityElementError!KeyPair { |
| 45 | const ss = seed orelse ss: { | 52 | const ss = seed orelse ss: { |
| 46 | var random_seed: [seed_length]u8 = undefined; | 53 | var random_seed: [seed_length]u8 = undefined; |
| 47 | crypto.random.bytes(&random_seed); | 54 | crypto.random.bytes(&random_seed); |
| ... | @@ -51,7 +58,7 @@ pub const Ed25519 = struct { | ... | @@ -51,7 +58,7 @@ pub const Ed25519 = struct { |
| 51 | var h = Sha512.init(.{}); | 58 | var h = Sha512.init(.{}); |
| 52 | h.update(&ss); | 59 | h.update(&ss); |
| 53 | h.final(&az); | 60 | h.final(&az); |
| 54 | const p = try Curve.basePoint.clampedMul(az[0..32].*); | 61 | const p = Curve.basePoint.clampedMul(az[0..32].*) catch return error.IdentityElement; |
| 55 | var sk: [secret_length]u8 = undefined; | 62 | var sk: [secret_length]u8 = undefined; |
| 56 | mem.copy(u8, &sk, &ss); | 63 | mem.copy(u8, &sk, &ss); |
| 57 | const pk = p.toBytes(); | 64 | const pk = p.toBytes(); |
| ... | @@ -72,7 +79,7 @@ pub const Ed25519 = struct { | ... | @@ -72,7 +79,7 @@ pub const Ed25519 = struct { |
| 72 | /// Sign a message using a key pair, and optional random noise. | 79 | /// Sign a message using a key pair, and optional random noise. |
| 73 | /// Having noise creates non-standard, non-deterministic signatures, | 80 | /// Having noise creates non-standard, non-deterministic signatures, |
| 74 | /// but has been proven to increase resilience against fault attacks. | 81 | /// but has been proven to increase resilience against fault attacks. |
| 75 | pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) Error![signature_length]u8 { | 82 | pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) (IdentityElementError || WeakPublicKeyError || KeyMismatchError)![signature_length]u8 { |
| 76 | const seed = key_pair.secret_key[0..seed_length]; | 83 | const seed = key_pair.secret_key[0..seed_length]; |
| 77 | const public_key = key_pair.secret_key[seed_length..]; | 84 | const public_key = key_pair.secret_key[seed_length..]; |
| 78 | if (!mem.eql(u8, public_key, &key_pair.public_key)) { | 85 | if (!mem.eql(u8, public_key, &key_pair.public_key)) { |
| ... | @@ -113,7 +120,7 @@ pub const Ed25519 = struct { | ... | @@ -113,7 +120,7 @@ pub const Ed25519 = struct { |
| 113 | 120 | ||
| 114 | /// Verify an Ed25519 signature given a message and a public key. | 121 | /// Verify an Ed25519 signature given a message and a public key. |
| 115 | /// Returns error.SignatureVerificationFailed is the signature verification failed. | 122 | /// Returns error.SignatureVerificationFailed is the signature verification failed. |
| 116 | pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) Error!void { | 123 | pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) (SignatureVerificationError || WeakPublicKeyError || EncodingError || NonCanonicalError || IdentityElementError)!void { |
| 117 | const r = sig[0..32]; | 124 | const r = sig[0..32]; |
| 118 | const s = sig[32..64]; | 125 | const s = sig[32..64]; |
| 119 | try Curve.scalar.rejectNonCanonical(s.*); | 126 | try Curve.scalar.rejectNonCanonical(s.*); |
| ... | @@ -146,7 +153,7 @@ pub const Ed25519 = struct { | ... | @@ -146,7 +153,7 @@ pub const Ed25519 = struct { |
| 146 | }; | 153 | }; |
| 147 | 154 | ||
| 148 | /// Verify several signatures in a single operation, much faster than verifying signatures one-by-one | 155 | /// Verify several signatures in a single operation, much faster than verifying signatures one-by-one |
| 149 | pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) Error!void { | 156 | pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) (SignatureVerificationError || IdentityElementError || WeakPublicKeyError || EncodingError || NonCanonicalError)!void { |
| 150 | var r_batch: [count][32]u8 = undefined; | 157 | var r_batch: [count][32]u8 = undefined; |
| 151 | var s_batch: [count][32]u8 = undefined; | 158 | var s_batch: [count][32]u8 = undefined; |
| 152 | var a_batch: [count]Curve = undefined; | 159 | var a_batch: [count]Curve = undefined; |
| ... | @@ -180,7 +187,7 @@ pub const Ed25519 = struct { | ... | @@ -180,7 +187,7 @@ pub const Ed25519 = struct { |
| 180 | 187 | ||
| 181 | var z_batch: [count]Curve.scalar.CompressedScalar = undefined; | 188 | var z_batch: [count]Curve.scalar.CompressedScalar = undefined; |
| 182 | for (z_batch) |*z| { | 189 | for (z_batch) |*z| { |
| 183 | std.crypto.random.bytes(z[0..16]); | 190 | crypto.random.bytes(z[0..16]); |
| 184 | mem.set(u8, z[16..], 0); | 191 | mem.set(u8, z[16..], 0); |
| 185 | } | 192 | } |
| 186 | 193 | ||
| ... | @@ -233,8 +240,8 @@ test "ed25519 batch verification" { | ... | @@ -233,8 +240,8 @@ test "ed25519 batch verification" { |
| 233 | const key_pair = try Ed25519.KeyPair.create(null); | 240 | const key_pair = try Ed25519.KeyPair.create(null); |
| 234 | var msg1: [32]u8 = undefined; | 241 | var msg1: [32]u8 = undefined; |
| 235 | var msg2: [32]u8 = undefined; | 242 | var msg2: [32]u8 = undefined; |
| 236 | std.crypto.random.bytes(&msg1); | 243 | crypto.random.bytes(&msg1); |
| 237 | std.crypto.random.bytes(&msg2); | 244 | crypto.random.bytes(&msg2); |
| 238 | const sig1 = try Ed25519.sign(&msg1, key_pair, null); | 245 | const sig1 = try Ed25519.sign(&msg1, key_pair, null); |
| 239 | const sig2 = try Ed25519.sign(&msg2, key_pair, null); | 246 | const sig2 = try Ed25519.sign(&msg2, key_pair, null); |
| 240 | var signature_batch = [_]Ed25519.BatchElement{ | 247 | var signature_batch = [_]Ed25519.BatchElement{ |
lib/std/crypto/25519/edwards25519.zig+23-17| ... | @@ -4,10 +4,16 @@ | ... | @@ -4,10 +4,16 @@ |
| 4 | // The MIT license requires this copyright notice to be included in all copies | 4 | // 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. |
| 6 | const std = @import("std"); | 6 | const std = @import("std"); |
| 7 | const crypto = std.crypto; | ||
| 7 | const debug = std.debug; | 8 | const debug = std.debug; |
| 8 | const fmt = std.fmt; | 9 | const fmt = std.fmt; |
| 9 | const mem = std.mem; | 10 | const mem = std.mem; |
| 10 | const Error = std.crypto.Error; | 11 | |
| 12 | const EncodingError = crypto.errors.EncodingError; | ||
| 13 | const IdentityElementError = crypto.errors.IdentityElementError; | ||
| 14 | const NonCanonicalError = crypto.errors.NonCanonicalError; | ||
| 15 | const NotSquareError = crypto.errors.NotSquareError; | ||
| 16 | const WeakPublicKeyError = crypto.errors.WeakPublicKeyError; | ||
| 11 | 17 | ||
| 12 | /// Group operations over Edwards25519. | 18 | /// Group operations over Edwards25519. |
| 13 | pub const Edwards25519 = struct { | 19 | pub const Edwards25519 = struct { |
| ... | @@ -26,7 +32,7 @@ pub const Edwards25519 = struct { | ... | @@ -26,7 +32,7 @@ pub const Edwards25519 = struct { |
| 26 | is_base: bool = false, | 32 | is_base: bool = false, |
| 27 | 33 | ||
| 28 | /// Decode an Edwards25519 point from its compressed (Y+sign) coordinates. | 34 | /// Decode an Edwards25519 point from its compressed (Y+sign) coordinates. |
| 29 | pub fn fromBytes(s: [encoded_length]u8) Error!Edwards25519 { | 35 | pub fn fromBytes(s: [encoded_length]u8) EncodingError!Edwards25519 { |
| 30 | const z = Fe.one; | 36 | const z = Fe.one; |
| 31 | const y = Fe.fromBytes(s); | 37 | const y = Fe.fromBytes(s); |
| 32 | var u = y.sq(); | 38 | var u = y.sq(); |
| ... | @@ -56,7 +62,7 @@ pub const Edwards25519 = struct { | ... | @@ -56,7 +62,7 @@ pub const Edwards25519 = struct { |
| 56 | } | 62 | } |
| 57 | 63 | ||
| 58 | /// Check that the encoding of a point is canonical. | 64 | /// Check that the encoding of a point is canonical. |
| 59 | pub fn rejectNonCanonical(s: [32]u8) Error!void { | 65 | pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void { |
| 60 | return Fe.rejectNonCanonical(s, true); | 66 | return Fe.rejectNonCanonical(s, true); |
| 61 | } | 67 | } |
| 62 | 68 | ||
| ... | @@ -81,7 +87,7 @@ pub const Edwards25519 = struct { | ... | @@ -81,7 +87,7 @@ pub const Edwards25519 = struct { |
| 81 | const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero }; | 87 | const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero }; |
| 82 | 88 | ||
| 83 | /// Reject the neutral element. | 89 | /// Reject the neutral element. |
| 84 | pub fn rejectIdentity(p: Edwards25519) Error!void { | 90 | pub fn rejectIdentity(p: Edwards25519) IdentityElementError!void { |
| 85 | if (p.x.isZero()) { | 91 | if (p.x.isZero()) { |
| 86 | return error.IdentityElement; | 92 | return error.IdentityElement; |
| 87 | } | 93 | } |
| ... | @@ -177,7 +183,7 @@ pub const Edwards25519 = struct { | ... | @@ -177,7 +183,7 @@ pub const Edwards25519 = struct { |
| 177 | // Based on real-world benchmarks, we only use this for multi-scalar multiplication. | 183 | // Based on real-world benchmarks, we only use this for multi-scalar multiplication. |
| 178 | // NAF could be useful to half the size of precomputation tables, but we intentionally | 184 | // NAF could be useful to half the size of precomputation tables, but we intentionally |
| 179 | // avoid these to keep the standard library lightweight. | 185 | // avoid these to keep the standard library lightweight. |
| 180 | fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 { | 186 | fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 { |
| 181 | std.debug.assert(vartime); | 187 | std.debug.assert(vartime); |
| 182 | const e = nonAdjacentForm(s); | 188 | const e = nonAdjacentForm(s); |
| 183 | var q = Edwards25519.identityElement; | 189 | var q = Edwards25519.identityElement; |
| ... | @@ -197,7 +203,7 @@ pub const Edwards25519 = struct { | ... | @@ -197,7 +203,7 @@ pub const Edwards25519 = struct { |
| 197 | } | 203 | } |
| 198 | 204 | ||
| 199 | // Scalar multiplication with a 4-bit window and the first 15 multiples. | 205 | // Scalar multiplication with a 4-bit window and the first 15 multiples. |
| 200 | fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 { | 206 | fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 { |
| 201 | var q = Edwards25519.identityElement; | 207 | var q = Edwards25519.identityElement; |
| 202 | var pos: usize = 252; | 208 | var pos: usize = 252; |
| 203 | while (true) : (pos -= 4) { | 209 | while (true) : (pos -= 4) { |
| ... | @@ -233,12 +239,12 @@ pub const Edwards25519 = struct { | ... | @@ -233,12 +239,12 @@ pub const Edwards25519 = struct { |
| 233 | }; | 239 | }; |
| 234 | 240 | ||
| 235 | /// Multiply an Edwards25519 point by a scalar without clamping it. | 241 | /// Multiply an Edwards25519 point by a scalar without clamping it. |
| 236 | /// Return error.WeakPublicKey if the resulting point is | 242 | /// Return error.WeakPublicKey if the base generates a small-order group, |
| 237 | /// the identity element. | 243 | /// and error.IdentityElement if the result is the identity element. |
| 238 | pub fn mul(p: Edwards25519, s: [32]u8) Error!Edwards25519 { | 244 | pub fn mul(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 { |
| 239 | const pc = if (p.is_base) basePointPc else pc: { | 245 | const pc = if (p.is_base) basePointPc else pc: { |
| 240 | const xpc = precompute(p, 15); | 246 | const xpc = precompute(p, 15); |
| 241 | xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey; | 247 | xpc[4].rejectIdentity() catch return error.WeakPublicKey; |
| 242 | break :pc xpc; | 248 | break :pc xpc; |
| 243 | }; | 249 | }; |
| 244 | return pcMul16(pc, s, false); | 250 | return pcMul16(pc, s, false); |
| ... | @@ -246,7 +252,7 @@ pub const Edwards25519 = struct { | ... | @@ -246,7 +252,7 @@ pub const Edwards25519 = struct { |
| 246 | 252 | ||
| 247 | /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME* | 253 | /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME* |
| 248 | /// This can be used for signature verification. | 254 | /// This can be used for signature verification. |
| 249 | pub fn mulPublic(p: Edwards25519, s: [32]u8) Error!Edwards25519 { | 255 | pub fn mulPublic(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 { |
| 250 | if (p.is_base) { | 256 | if (p.is_base) { |
| 251 | return pcMul16(basePointPc, s, true); | 257 | return pcMul16(basePointPc, s, true); |
| 252 | } else { | 258 | } else { |
| ... | @@ -258,7 +264,7 @@ pub const Edwards25519 = struct { | ... | @@ -258,7 +264,7 @@ pub const Edwards25519 = struct { |
| 258 | 264 | ||
| 259 | /// Multiscalar multiplication *IN VARIABLE TIME* for public data | 265 | /// Multiscalar multiplication *IN VARIABLE TIME* for public data |
| 260 | /// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually | 266 | /// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually |
| 261 | pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) Error!Edwards25519 { | 267 | pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 { |
| 262 | var pcs: [count][9]Edwards25519 = undefined; | 268 | var pcs: [count][9]Edwards25519 = undefined; |
| 263 | for (ps) |p, i| { | 269 | for (ps) |p, i| { |
| 264 | if (p.is_base) { | 270 | if (p.is_base) { |
| ... | @@ -297,14 +303,14 @@ pub const Edwards25519 = struct { | ... | @@ -297,14 +303,14 @@ pub const Edwards25519 = struct { |
| 297 | /// This is strongly recommended for DH operations. | 303 | /// This is strongly recommended for DH operations. |
| 298 | /// Return error.WeakPublicKey if the resulting point is | 304 | /// Return error.WeakPublicKey if the resulting point is |
| 299 | /// the identity element. | 305 | /// the identity element. |
| 300 | pub fn clampedMul(p: Edwards25519, s: [32]u8) Error!Edwards25519 { | 306 | pub fn clampedMul(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 { |
| 301 | var t: [32]u8 = s; | 307 | var t: [32]u8 = s; |
| 302 | scalar.clamp(&t); | 308 | scalar.clamp(&t); |
| 303 | return mul(p, t); | 309 | return mul(p, t); |
| 304 | } | 310 | } |
| 305 | 311 | ||
| 306 | // montgomery -- recover y = sqrt(x^3 + A*x^2 + x) | 312 | // montgomery -- recover y = sqrt(x^3 + A*x^2 + x) |
| 307 | fn xmontToYmont(x: Fe) Error!Fe { | 313 | fn xmontToYmont(x: Fe) NotSquareError!Fe { |
| 308 | var x2 = x.sq(); | 314 | var x2 = x.sq(); |
| 309 | const x3 = x.mul(x2); | 315 | const x3 = x.mul(x2); |
| 310 | x2 = x2.mul32(Fe.edwards25519a_32); | 316 | x2 = x2.mul32(Fe.edwards25519a_32); |
| ... | @@ -367,7 +373,7 @@ pub const Edwards25519 = struct { | ... | @@ -367,7 +373,7 @@ pub const Edwards25519 = struct { |
| 367 | 373 | ||
| 368 | fn stringToPoints(comptime n: usize, ctx: []const u8, s: []const u8) [n]Edwards25519 { | 374 | fn stringToPoints(comptime n: usize, ctx: []const u8, s: []const u8) [n]Edwards25519 { |
| 369 | debug.assert(n <= 2); | 375 | debug.assert(n <= 2); |
| 370 | const H = std.crypto.hash.sha2.Sha512; | 376 | const H = crypto.hash.sha2.Sha512; |
| 371 | const h_l: usize = 48; | 377 | const h_l: usize = 48; |
| 372 | var xctx = ctx; | 378 | var xctx = ctx; |
| 373 | var hctx: [H.digest_length]u8 = undefined; | 379 | var hctx: [H.digest_length]u8 = undefined; |
| ... | @@ -485,8 +491,8 @@ test "edwards25519 packing/unpacking" { | ... | @@ -485,8 +491,8 @@ test "edwards25519 packing/unpacking" { |
| 485 | test "edwards25519 point addition/substraction" { | 491 | test "edwards25519 point addition/substraction" { |
| 486 | var s1: [32]u8 = undefined; | 492 | var s1: [32]u8 = undefined; |
| 487 | var s2: [32]u8 = undefined; | 493 | var s2: [32]u8 = undefined; |
| 488 | std.crypto.random.bytes(&s1); | 494 | crypto.random.bytes(&s1); |
| 489 | std.crypto.random.bytes(&s2); | 495 | crypto.random.bytes(&s2); |
| 490 | const p = try Edwards25519.basePoint.clampedMul(s1); | 496 | const p = try Edwards25519.basePoint.clampedMul(s1); |
| 491 | const q = try Edwards25519.basePoint.clampedMul(s2); | 497 | const q = try Edwards25519.basePoint.clampedMul(s2); |
| 492 | const r = p.add(q).add(q).sub(q).sub(q); | 498 | const r = p.add(q).add(q).sub(q).sub(q); |
lib/std/crypto/25519/field.zig+6-3| ... | @@ -4,9 +4,12 @@ | ... | @@ -4,9 +4,12 @@ |
| 4 | // The MIT license requires this copyright notice to be included in all copies | 4 | // 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. |
| 6 | const std = @import("std"); | 6 | const std = @import("std"); |
| 7 | const crypto = std.crypto; | ||
| 7 | const readIntLittle = std.mem.readIntLittle; | 8 | const readIntLittle = std.mem.readIntLittle; |
| 8 | const writeIntLittle = std.mem.writeIntLittle; | 9 | const writeIntLittle = std.mem.writeIntLittle; |
| 9 | const Error = std.crypto.Error; | 10 | |
| 11 | const NonCanonicalError = crypto.errors.NonCanonicalError; | ||
| 12 | const NotSquareError = crypto.errors.NotSquareError; | ||
| 10 | 13 | ||
| 11 | pub const Fe = struct { | 14 | pub const Fe = struct { |
| 12 | limbs: [5]u64, | 15 | limbs: [5]u64, |
| ... | @@ -113,7 +116,7 @@ pub const Fe = struct { | ... | @@ -113,7 +116,7 @@ pub const Fe = struct { |
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | /// Reject non-canonical encodings of an element, possibly ignoring the top bit | 118 | /// Reject non-canonical encodings of an element, possibly ignoring the top bit |
| 116 | pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) Error!void { | 119 | pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) NonCanonicalError!void { |
| 117 | var c: u16 = (s[31] & 0x7f) ^ 0x7f; | 120 | var c: u16 = (s[31] & 0x7f) ^ 0x7f; |
| 118 | comptime var i = 30; | 121 | comptime var i = 30; |
| 119 | inline while (i > 0) : (i -= 1) { | 122 | inline while (i > 0) : (i -= 1) { |
| ... | @@ -413,7 +416,7 @@ pub const Fe = struct { | ... | @@ -413,7 +416,7 @@ pub const Fe = struct { |
| 413 | } | 416 | } |
| 414 | 417 | ||
| 415 | /// Compute the square root of `x2`, returning `error.NotSquare` if `x2` was not a square | 418 | /// Compute the square root of `x2`, returning `error.NotSquare` if `x2` was not a square |
| 416 | pub fn sqrt(x2: Fe) Error!Fe { | 419 | pub fn sqrt(x2: Fe) NotSquareError!Fe { |
| 417 | var x2_copy = x2; | 420 | var x2_copy = x2; |
| 418 | const x = x2.uncheckedSqrt(); | 421 | const x = x2.uncheckedSqrt(); |
| 419 | const check = x.sq().sub(x2_copy); | 422 | const check = x.sq().sub(x2_copy); |
lib/std/crypto/25519/ristretto255.zig+9-5| ... | @@ -5,7 +5,11 @@ | ... | @@ -5,7 +5,11 @@ |
| 5 | // and substantial portions of the software. | 5 | // and substantial portions of the software. |
| 6 | const std = @import("std"); | 6 | const std = @import("std"); |
| 7 | const fmt = std.fmt; | 7 | const fmt = std.fmt; |
| 8 | const Error = std.crypto.Error; | 8 | |
| 9 | const EncodingError = std.crypto.errors.EncodingError; | ||
| 10 | const IdentityElementError = std.crypto.errors.IdentityElementError; | ||
| 11 | const NonCanonicalError = std.crypto.errors.NonCanonicalError; | ||
| 12 | const WeakPublicKeyError = std.crypto.errors.WeakPublicKeyError; | ||
| 9 | 13 | ||
| 10 | /// Group operations over Edwards25519. | 14 | /// Group operations over Edwards25519. |
| 11 | pub const Ristretto255 = struct { | 15 | pub const Ristretto255 = struct { |
| ... | @@ -35,7 +39,7 @@ pub const Ristretto255 = struct { | ... | @@ -35,7 +39,7 @@ pub const Ristretto255 = struct { |
| 35 | return .{ .ratio_is_square = @boolToInt(has_m_root) | @boolToInt(has_p_root), .root = x.abs() }; | 39 | return .{ .ratio_is_square = @boolToInt(has_m_root) | @boolToInt(has_p_root), .root = x.abs() }; |
| 36 | } | 40 | } |
| 37 | 41 | ||
| 38 | fn rejectNonCanonical(s: [encoded_length]u8) Error!void { | 42 | fn rejectNonCanonical(s: [encoded_length]u8) NonCanonicalError!void { |
| 39 | if ((s[0] & 1) != 0) { | 43 | if ((s[0] & 1) != 0) { |
| 40 | return error.NonCanonical; | 44 | return error.NonCanonical; |
| 41 | } | 45 | } |
| ... | @@ -43,7 +47,7 @@ pub const Ristretto255 = struct { | ... | @@ -43,7 +47,7 @@ pub const Ristretto255 = struct { |
| 43 | } | 47 | } |
| 44 | 48 | ||
| 45 | /// Reject the neutral element. | 49 | /// Reject the neutral element. |
| 46 | pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) Error!void { | 50 | pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) IdentityElementError!void { |
| 47 | return p.p.rejectIdentity(); | 51 | return p.p.rejectIdentity(); |
| 48 | } | 52 | } |
| 49 | 53 | ||
| ... | @@ -51,7 +55,7 @@ pub const Ristretto255 = struct { | ... | @@ -51,7 +55,7 @@ pub const Ristretto255 = struct { |
| 51 | pub const basePoint = Ristretto255{ .p = Curve.basePoint }; | 55 | pub const basePoint = Ristretto255{ .p = Curve.basePoint }; |
| 52 | 56 | ||
| 53 | /// Decode a Ristretto255 representative. | 57 | /// Decode a Ristretto255 representative. |
| 54 | pub fn fromBytes(s: [encoded_length]u8) Error!Ristretto255 { | 58 | pub fn fromBytes(s: [encoded_length]u8) (NonCanonicalError || EncodingError)!Ristretto255 { |
| 55 | try rejectNonCanonical(s); | 59 | try rejectNonCanonical(s); |
| 56 | const s_ = Fe.fromBytes(s); | 60 | const s_ = Fe.fromBytes(s); |
| 57 | const ss = s_.sq(); // s^2 | 61 | const ss = s_.sq(); // s^2 |
| ... | @@ -154,7 +158,7 @@ pub const Ristretto255 = struct { | ... | @@ -154,7 +158,7 @@ pub const Ristretto255 = struct { |
| 154 | /// Multiply a Ristretto255 element with a scalar. | 158 | /// Multiply a Ristretto255 element with a scalar. |
| 155 | /// Return error.WeakPublicKey if the resulting element is | 159 | /// Return error.WeakPublicKey if the resulting element is |
| 156 | /// the identity element. | 160 | /// the identity element. |
| 157 | pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) Error!Ristretto255 { | 161 | pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) (IdentityElementError || WeakPublicKeyError)!Ristretto255 { |
| 158 | return Ristretto255{ .p = try p.p.mul(s) }; | 162 | return Ristretto255{ .p = try p.p.mul(s) }; |
| 159 | } | 163 | } |
| 160 | 164 |
lib/std/crypto/25519/scalar.zig+3-2| ... | @@ -5,7 +5,8 @@ | ... | @@ -5,7 +5,8 @@ |
| 5 | // and substantial portions of the software. | 5 | // and substantial portions of the software. |
| 6 | const std = @import("std"); | 6 | const std = @import("std"); |
| 7 | const mem = std.mem; | 7 | const mem = std.mem; |
| 8 | const Error = std.crypto.Error; | 8 | |
| 9 | const NonCanonicalError = std.crypto.errors.NonCanonicalError; | ||
| 9 | 10 | ||
| 10 | /// 2^252 + 27742317777372353535851937790883648493 | 11 | /// 2^252 + 27742317777372353535851937790883648493 |
| 11 | pub const field_size = [32]u8{ | 12 | pub const field_size = [32]u8{ |
| ... | @@ -19,7 +20,7 @@ pub const CompressedScalar = [32]u8; | ... | @@ -19,7 +20,7 @@ pub const CompressedScalar = [32]u8; |
| 19 | pub const zero = [_]u8{0} ** 32; | 20 | pub const zero = [_]u8{0} ** 32; |
| 20 | 21 | ||
| 21 | /// Reject a scalar whose encoding is not canonical. | 22 | /// Reject a scalar whose encoding is not canonical. |
| 22 | pub fn rejectNonCanonical(s: [32]u8) Error!void { | 23 | pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void { |
| 23 | var c: u8 = 0; | 24 | var c: u8 = 0; |
| 24 | var n: u8 = 1; | 25 | var n: u8 = 1; |
| 25 | var i: usize = 31; | 26 | var i: usize = 31; |
lib/std/crypto/25519/x25519.zig+9-6| ... | @@ -9,7 +9,10 @@ const mem = std.mem; | ... | @@ -9,7 +9,10 @@ const mem = std.mem; |
| 9 | const fmt = std.fmt; | 9 | const fmt = std.fmt; |
| 10 | 10 | ||
| 11 | const Sha512 = crypto.hash.sha2.Sha512; | 11 | const Sha512 = crypto.hash.sha2.Sha512; |
| 12 | const Error = crypto.Error; | 12 | |
| 13 | const EncodingError = crypto.errors.EncodingError; | ||
| 14 | const IdentityElementError = crypto.errors.IdentityElementError; | ||
| 15 | const WeakPublicKeyError = crypto.errors.WeakPublicKeyError; | ||
| 13 | 16 | ||
| 14 | /// X25519 DH function. | 17 | /// X25519 DH function. |
| 15 | pub const X25519 = struct { | 18 | pub const X25519 = struct { |
| ... | @@ -32,7 +35,7 @@ pub const X25519 = struct { | ... | @@ -32,7 +35,7 @@ pub const X25519 = struct { |
| 32 | secret_key: [secret_length]u8, | 35 | secret_key: [secret_length]u8, |
| 33 | 36 | ||
| 34 | /// Create a new key pair using an optional seed. | 37 | /// Create a new key pair using an optional seed. |
| 35 | pub fn create(seed: ?[seed_length]u8) Error!KeyPair { | 38 | pub fn create(seed: ?[seed_length]u8) IdentityElementError!KeyPair { |
| 36 | const sk = seed orelse sk: { | 39 | const sk = seed orelse sk: { |
| 37 | var random_seed: [seed_length]u8 = undefined; | 40 | var random_seed: [seed_length]u8 = undefined; |
| 38 | crypto.random.bytes(&random_seed); | 41 | crypto.random.bytes(&random_seed); |
| ... | @@ -45,7 +48,7 @@ pub const X25519 = struct { | ... | @@ -45,7 +48,7 @@ pub const X25519 = struct { |
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | /// Create a key pair from an Ed25519 key pair | 50 | /// Create a key pair from an Ed25519 key pair |
| 48 | pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) Error!KeyPair { | 51 | pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) (IdentityElementError || EncodingError)!KeyPair { |
| 49 | const seed = ed25519_key_pair.secret_key[0..32]; | 52 | const seed = ed25519_key_pair.secret_key[0..32]; |
| 50 | var az: [Sha512.digest_length]u8 = undefined; | 53 | var az: [Sha512.digest_length]u8 = undefined; |
| 51 | Sha512.hash(seed, &az, .{}); | 54 | Sha512.hash(seed, &az, .{}); |
| ... | @@ -60,13 +63,13 @@ pub const X25519 = struct { | ... | @@ -60,13 +63,13 @@ pub const X25519 = struct { |
| 60 | }; | 63 | }; |
| 61 | 64 | ||
| 62 | /// Compute the public key for a given private key. | 65 | /// Compute the public key for a given private key. |
| 63 | pub fn recoverPublicKey(secret_key: [secret_length]u8) Error![public_length]u8 { | 66 | pub fn recoverPublicKey(secret_key: [secret_length]u8) IdentityElementError![public_length]u8 { |
| 64 | const q = try Curve.basePoint.clampedMul(secret_key); | 67 | const q = try Curve.basePoint.clampedMul(secret_key); |
| 65 | return q.toBytes(); | 68 | return q.toBytes(); |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | /// Compute the X25519 equivalent to an Ed25519 public eky. | 71 | /// Compute the X25519 equivalent to an Ed25519 public eky. |
| 69 | pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) Error![public_length]u8 { | 72 | pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) (IdentityElementError || EncodingError)![public_length]u8 { |
| 70 | const pk_ed = try crypto.ecc.Edwards25519.fromBytes(ed25519_public_key); | 73 | const pk_ed = try crypto.ecc.Edwards25519.fromBytes(ed25519_public_key); |
| 71 | const pk = try Curve.fromEdwards25519(pk_ed); | 74 | const pk = try Curve.fromEdwards25519(pk_ed); |
| 72 | return pk.toBytes(); | 75 | return pk.toBytes(); |
| ... | @@ -75,7 +78,7 @@ pub const X25519 = struct { | ... | @@ -75,7 +78,7 @@ pub const X25519 = struct { |
| 75 | /// Compute the scalar product of a public key and a secret scalar. | 78 | /// Compute the scalar product of a public key and a secret scalar. |
| 76 | /// Note that the output should not be used as a shared secret without | 79 | /// Note that the output should not be used as a shared secret without |
| 77 | /// hashing it first. | 80 | /// hashing it first. |
| 78 | pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) Error![shared_length]u8 { | 81 | pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) IdentityElementError![shared_length]u8 { |
| 79 | const q = try Curve.fromBytes(public_key).clampedMul(secret_key); | 82 | const q = try Curve.fromBytes(public_key).clampedMul(secret_key); |
| 80 | return q.toBytes(); | 83 | return q.toBytes(); |
| 81 | } | 84 | } |
lib/std/crypto/aegis.zig+3-3| ... | @@ -8,7 +8,7 @@ const std = @import("std"); | ... | @@ -8,7 +8,7 @@ const std = @import("std"); |
| 8 | const mem = std.mem; | 8 | const mem = std.mem; |
| 9 | const assert = std.debug.assert; | 9 | const assert = std.debug.assert; |
| 10 | const AesBlock = std.crypto.core.aes.Block; | 10 | const AesBlock = std.crypto.core.aes.Block; |
| 11 | const Error = std.crypto.Error; | 11 | const AuthenticationError = std.crypto.errors.AuthenticationError; |
| 12 | 12 | ||
| 13 | const State128L = struct { | 13 | const State128L = struct { |
| 14 | blocks: [8]AesBlock, | 14 | blocks: [8]AesBlock, |
| ... | @@ -137,7 +137,7 @@ pub const Aegis128L = struct { | ... | @@ -137,7 +137,7 @@ pub const Aegis128L = struct { |
| 137 | /// ad: Associated Data | 137 | /// ad: Associated Data |
| 138 | /// npub: public nonce | 138 | /// npub: public nonce |
| 139 | /// k: private key | 139 | /// k: private key |
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void { |
| 141 | assert(c.len == m.len); | 141 | assert(c.len == m.len); |
| 142 | var state = State128L.init(key, npub); | 142 | var state = State128L.init(key, npub); |
| 143 | var src: [32]u8 align(16) = undefined; | 143 | var src: [32]u8 align(16) = undefined; |
| ... | @@ -299,7 +299,7 @@ pub const Aegis256 = struct { | ... | @@ -299,7 +299,7 @@ pub const Aegis256 = struct { |
| 299 | /// ad: Associated Data | 299 | /// ad: Associated Data |
| 300 | /// npub: public nonce | 300 | /// npub: public nonce |
| 301 | /// k: private key | 301 | /// k: private key |
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void { |
| 303 | assert(c.len == m.len); | 303 | assert(c.len == m.len); |
| 304 | var state = State256.init(key, npub); | 304 | var state = State256.init(key, npub); |
| 305 | var src: [16]u8 align(16) = undefined; | 305 | var src: [16]u8 align(16) = undefined; |
lib/std/crypto/aes_gcm.zig+2-2| ... | @@ -12,7 +12,7 @@ const debug = std.debug; | ... | @@ -12,7 +12,7 @@ const debug = std.debug; |
| 12 | const Ghash = std.crypto.onetimeauth.Ghash; | 12 | const Ghash = std.crypto.onetimeauth.Ghash; |
| 13 | const mem = std.mem; | 13 | const mem = std.mem; |
| 14 | const modes = crypto.core.modes; | 14 | const modes = crypto.core.modes; |
| 15 | const Error = crypto.Error; | 15 | const AuthenticationError = crypto.errors.AuthenticationError; |
| 16 | 16 | ||
| 17 | pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128); | 17 | pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128); |
| 18 | pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256); | 18 | pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256); |
| ... | @@ -60,7 +60,7 @@ fn AesGcm(comptime Aes: anytype) type { | ... | @@ -60,7 +60,7 @@ fn AesGcm(comptime Aes: anytype) type { |
| 60 | } | 60 | } |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void { |
| 64 | assert(c.len == m.len); | 64 | assert(c.len == m.len); |
| 65 | 65 | ||
| 66 | const aes = Aes.initEnc(key); | 66 | const aes = Aes.initEnc(key); |
lib/std/crypto/aes_ocb.zig+2-2| ... | @@ -10,7 +10,7 @@ const aes = crypto.core.aes; | ... | @@ -10,7 +10,7 @@ const aes = crypto.core.aes; |
| 10 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 11 | const math = std.math; | 11 | const math = std.math; |
| 12 | const mem = std.mem; | 12 | const mem = std.mem; |
| 13 | const Error = crypto.Error; | 13 | const AuthenticationError = crypto.errors.AuthenticationError; |
| 14 | 14 | ||
| 15 | pub const Aes128Ocb = AesOcb(aes.Aes128); | 15 | pub const Aes128Ocb = AesOcb(aes.Aes128); |
| 16 | pub const Aes256Ocb = AesOcb(aes.Aes256); | 16 | pub const Aes256Ocb = AesOcb(aes.Aes256); |
| ... | @@ -179,7 +179,7 @@ fn AesOcb(comptime Aes: anytype) type { | ... | @@ -179,7 +179,7 @@ fn AesOcb(comptime Aes: anytype) type { |
| 179 | /// ad: Associated Data | 179 | /// ad: Associated Data |
| 180 | /// npub: public nonce | 180 | /// npub: public nonce |
| 181 | /// k: secret key | 181 | /// k: secret key |
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void { |
| 183 | assert(c.len == m.len); | 183 | assert(c.len == m.len); |
| 184 | 184 | ||
| 185 | const aes_enc_ctx = Aes.initEnc(key); | 185 | const aes_enc_ctx = Aes.initEnc(key); |
lib/std/crypto/bcrypt.zig+6-5| ... | @@ -12,7 +12,8 @@ const mem = std.mem; | ... | @@ -12,7 +12,8 @@ const mem = std.mem; |
| 12 | const debug = std.debug; | 12 | const debug = std.debug; |
| 13 | const testing = std.testing; | 13 | const testing = std.testing; |
| 14 | const utils = crypto.utils; | 14 | const utils = crypto.utils; |
| 15 | const Error = crypto.Error; | 15 | const EncodingError = crypto.errors.EncodingError; |
| 16 | const PasswordVerificationError = crypto.errors.PasswordVerificationError; | ||
| 16 | 17 | ||
| 17 | const salt_length: usize = 16; | 18 | const salt_length: usize = 16; |
| 18 | const salt_str_length: usize = 22; | 19 | const salt_str_length: usize = 22; |
| ... | @@ -179,7 +180,7 @@ const Codec = struct { | ... | @@ -179,7 +180,7 @@ const Codec = struct { |
| 179 | debug.assert(j == b64.len); | 180 | debug.assert(j == b64.len); |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | fn decode(bin: []u8, b64: []const u8) Error!void { | 183 | fn decode(bin: []u8, b64: []const u8) EncodingError!void { |
| 183 | var i: usize = 0; | 184 | var i: usize = 0; |
| 184 | var j: usize = 0; | 185 | var j: usize = 0; |
| 185 | while (j < bin.len) { | 186 | while (j < bin.len) { |
| ... | @@ -204,7 +205,7 @@ const Codec = struct { | ... | @@ -204,7 +205,7 @@ const Codec = struct { |
| 204 | } | 205 | } |
| 205 | }; | 206 | }; |
| 206 | 207 | ||
| 207 | fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) Error![hash_length]u8 { | 208 | fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) ![hash_length]u8 { |
| 208 | var state = State{}; | 209 | var state = State{}; |
| 209 | var password_buf: [73]u8 = undefined; | 210 | var password_buf: [73]u8 = undefined; |
| 210 | const trimmed_len = math.min(password.len, password_buf.len - 1); | 211 | const trimmed_len = math.min(password.len, password_buf.len - 1); |
| ... | @@ -252,14 +253,14 @@ fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) | ... | @@ -252,14 +253,14 @@ fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) |
| 252 | /// IMPORTANT: by design, bcrypt silently truncates passwords to 72 bytes. | 253 | /// IMPORTANT: by design, bcrypt silently truncates passwords to 72 bytes. |
| 253 | /// If this is an issue for your application, hash the password first using a function such as SHA-512, | 254 | /// If this is an issue for your application, hash the password first using a function such as SHA-512, |
| 254 | /// and then use the resulting hash as the password parameter for bcrypt. | 255 | /// and then use the resulting hash as the password parameter for bcrypt. |
| 255 | pub fn strHash(password: []const u8, rounds_log: u6) Error![hash_length]u8 { | 256 | pub fn strHash(password: []const u8, rounds_log: u6) ![hash_length]u8 { |
| 256 | var salt: [salt_length]u8 = undefined; | 257 | var salt: [salt_length]u8 = undefined; |
| 257 | crypto.random.bytes(&salt); | 258 | crypto.random.bytes(&salt); |
| 258 | return strHashInternal(password, rounds_log, salt); | 259 | return strHashInternal(password, rounds_log, salt); |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | /// Verify that a previously computed hash is valid for a given password. | 262 | /// Verify that a previously computed hash is valid for a given password. |
| 262 | pub fn strVerify(h: [hash_length]u8, password: []const u8) Error!void { | 263 | pub fn strVerify(h: [hash_length]u8, password: []const u8) (EncodingError || PasswordVerificationError)!void { |
| 263 | if (!mem.eql(u8, "$2", h[0..2])) return error.InvalidEncoding; | 264 | if (!mem.eql(u8, "$2", h[0..2])) return error.InvalidEncoding; |
| 264 | if (h[3] != '$' or h[6] != '$') return error.InvalidEncoding; | 265 | if (h[3] != '$' or h[6] != '$') return error.InvalidEncoding; |
| 265 | const rounds_log_str = h[4..][0..2]; | 266 | const rounds_log_str = h[4..][0..2]; |
lib/std/crypto/chacha20.zig+3-3| ... | @@ -13,7 +13,7 @@ const testing = std.testing; | ... | @@ -13,7 +13,7 @@ const testing = std.testing; |
| 13 | const maxInt = math.maxInt; | 13 | const maxInt = math.maxInt; |
| 14 | const Vector = std.meta.Vector; | 14 | const Vector = std.meta.Vector; |
| 15 | const Poly1305 = std.crypto.onetimeauth.Poly1305; | 15 | const Poly1305 = std.crypto.onetimeauth.Poly1305; |
| 16 | const Error = std.crypto.Error; | 16 | const AuthenticationError = std.crypto.errors.AuthenticationError; |
| 17 | 17 | ||
| 18 | /// IETF-variant of the ChaCha20 stream cipher, as designed for TLS. | 18 | /// IETF-variant of the ChaCha20 stream cipher, as designed for TLS. |
| 19 | pub const ChaCha20IETF = ChaChaIETF(20); | 19 | pub const ChaCha20IETF = ChaChaIETF(20); |
| ... | @@ -521,7 +521,7 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type { | ... | @@ -521,7 +521,7 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type { |
| 521 | /// npub: public nonce | 521 | /// npub: public nonce |
| 522 | /// k: private key | 522 | /// k: private key |
| 523 | /// NOTE: the check of the authentication tag is currently not done in constant time | 523 | /// NOTE: the check of the authentication tag is currently not done in constant time |
| 524 | 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 { | 524 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { |
| 525 | assert(c.len == m.len); | 525 | assert(c.len == m.len); |
| 526 | 526 | ||
| 527 | var polyKey = [_]u8{0} ** 32; | 527 | var polyKey = [_]u8{0} ** 32; |
| ... | @@ -583,7 +583,7 @@ fn XChaChaPoly1305(comptime rounds_nb: usize) type { | ... | @@ -583,7 +583,7 @@ fn XChaChaPoly1305(comptime rounds_nb: usize) type { |
| 583 | /// ad: Associated Data | 583 | /// ad: Associated Data |
| 584 | /// npub: public nonce | 584 | /// npub: public nonce |
| 585 | /// k: private key | 585 | /// k: private key |
| 586 | 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 { | 586 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { |
| 587 | const extended = extend(k, npub, rounds_nb); | 587 | const extended = extend(k, npub, rounds_nb); |
| 588 | return ChaChaPoly1305(rounds_nb).decrypt(m, c, tag, ad, extended.nonce, extended.key); | 588 | return ChaChaPoly1305(rounds_nb).decrypt(m, c, tag, ad, extended.nonce, extended.key); |
| 589 | } | 589 | } |
lib/std/crypto/error.zig deleted-34| ... | @@ -1,34 +0,0 @@ | ||
| 1 | pub 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/errors.zig created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | /// MAC verification failed - The tag doesn't verify for the given ciphertext and secret key | ||
| 2 | pub const AuthenticationError = error{AuthenticationFailed}; | ||
| 3 | |||
| 4 | /// The requested output length is too long for the chosen algorithm | ||
| 5 | pub const OutputTooLongError = error{OutputTooLong}; | ||
| 6 | |||
| 7 | /// Finite field operation returned the identity element | ||
| 8 | pub const IdentityElementError = error{IdentityElement}; | ||
| 9 | |||
| 10 | /// Encoded input cannot be decoded | ||
| 11 | pub const EncodingError = error{InvalidEncoding}; | ||
| 12 | |||
| 13 | /// The signature does't verify for the given message and public key | ||
| 14 | pub const SignatureVerificationError = error{SignatureVerificationFailed}; | ||
| 15 | |||
| 16 | /// Both a public and secret key have been provided, but they are incompatible | ||
| 17 | pub const KeyMismatchError = error{KeyMismatch}; | ||
| 18 | |||
| 19 | /// Encoded input is not in canonical form | ||
| 20 | pub const NonCanonicalError = error{NonCanonical}; | ||
| 21 | |||
| 22 | /// Square root has no solutions | ||
| 23 | pub const NotSquareError = error{NotSquare}; | ||
| 24 | |||
| 25 | /// Verification string doesn't match the provided password and parameters | ||
| 26 | pub const PasswordVerificationError = error{PasswordVerificationFailed}; | ||
| 27 | |||
| 28 | /// Parameters would be insecure to use | ||
| 29 | pub const WeakParametersError = error{WeakParameters}; | ||
| 30 | |||
| 31 | /// Public key would be insecure to use | ||
| 32 | pub const WeakPublicKeyError = error{WeakPublicKey}; | ||
| 33 | |||
| 34 | /// Any error related to cryptography operations | ||
| 35 | pub const Error = AuthenticationError || OutputTooLongError || IdentityElementError || EncodingError || SignatureVerificationError || KeyMismatchError || NonCanonicalError || NotSquareError || PasswordVerificationError || WeakParametersError || WeakPublicKeyError; | ||
lib/std/crypto/gimli.zig+2-2| ... | @@ -20,7 +20,7 @@ const assert = std.debug.assert; | ... | @@ -20,7 +20,7 @@ const assert = std.debug.assert; |
| 20 | const testing = std.testing; | 20 | const testing = std.testing; |
| 21 | const htest = @import("test.zig"); | 21 | const htest = @import("test.zig"); |
| 22 | const Vector = std.meta.Vector; | 22 | const Vector = std.meta.Vector; |
| 23 | const Error = std.crypto.Error; | 23 | const AuthenticationError = std.crypto.errors.AuthenticationError; |
| 24 | 24 | ||
| 25 | pub const State = struct { | 25 | pub const State = struct { |
| 26 | pub const BLOCKBYTES = 48; | 26 | pub const BLOCKBYTES = 48; |
| ... | @@ -393,7 +393,7 @@ pub const Aead = struct { | ... | @@ -393,7 +393,7 @@ pub const Aead = struct { |
| 393 | /// npub: public nonce | 393 | /// npub: public nonce |
| 394 | /// k: private key | 394 | /// k: private key |
| 395 | /// NOTE: the check of the authentication tag is currently not done in constant time | 395 | /// NOTE: the check of the authentication tag is currently not done in constant time |
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { |
| 397 | assert(c.len == m.len); | 397 | assert(c.len == m.len); |
| 398 | 398 | ||
| 399 | var state = Aead.init(ad, npub, k); | 399 | var state = Aead.init(ad, npub, k); |
lib/std/crypto/isap.zig+2-2| ... | @@ -3,7 +3,7 @@ const debug = std.debug; | ... | @@ -3,7 +3,7 @@ const debug = std.debug; |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const math = std.math; | 4 | const math = std.math; |
| 5 | const testing = std.testing; | 5 | const testing = std.testing; |
| 6 | const Error = std.crypto.Error; | 6 | const AuthenticationError = std.crypto.errors.AuthenticationError; |
| 7 | 7 | ||
| 8 | /// 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. |
| 9 | /// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-2/spec-doc-rnd2/isap-spec-round2.pdf | 9 | /// https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/round-2/spec-doc-rnd2/isap-spec-round2.pdf |
| ... | @@ -218,7 +218,7 @@ pub const IsapA128A = struct { | ... | @@ -218,7 +218,7 @@ pub const IsapA128A = struct { |
| 218 | tag.* = mac(c, ad, npub, key); | 218 | tag.* = mac(c, ad, npub, key); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 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 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, key: [key_length]u8) AuthenticationError!void { |
| 222 | var computed_tag = mac(c, ad, npub, key); | 222 | var computed_tag = mac(c, ad, npub, key); |
| 223 | var acc: u8 = 0; | 223 | var acc: u8 = 0; |
| 224 | for (computed_tag) |_, j| { | 224 | for (computed_tag) |_, j| { |
lib/std/crypto/pbkdf2.zig+3-2| ... | @@ -7,7 +7,8 @@ | ... | @@ -7,7 +7,8 @@ |
| 7 | const std = @import("std"); | 7 | const std = @import("std"); |
| 8 | const mem = std.mem; | 8 | const mem = std.mem; |
| 9 | const maxInt = std.math.maxInt; | 9 | const maxInt = std.math.maxInt; |
| 10 | const Error = std.crypto.Error; | 10 | const OutputTooLongError = std.crypto.errors.OutputTooLongError; |
| 11 | const WeakParametersError = std.crypto.errors.WeakParametersError; | ||
| 11 | 12 | ||
| 12 | // RFC 2898 Section 5.2 | 13 | // RFC 2898 Section 5.2 |
| 13 | // | 14 | // |
| ... | @@ -55,7 +56,7 @@ const Error = std.crypto.Error; | ... | @@ -55,7 +56,7 @@ const Error = std.crypto.Error; |
| 55 | /// the dk. It is common to tune this parameter to achieve approximately 100ms. | 56 | /// the dk. It is common to tune this parameter to achieve approximately 100ms. |
| 56 | /// | 57 | /// |
| 57 | /// Prf: Pseudo-random function to use. A common choice is `std.crypto.auth.hmac.HmacSha256`. | 58 | /// Prf: Pseudo-random function to use. A common choice is `std.crypto.auth.hmac.HmacSha256`. |
| 58 | pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) Error!void { | 59 | pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) (WeakParametersError || OutputTooLongError)!void { |
| 59 | if (rounds < 1) return error.WeakParameters; | 60 | if (rounds < 1) return error.WeakParameters; |
| 60 | 61 | ||
| 61 | const dk_len = dk.len; | 62 | const dk_len = dk.len; |
lib/std/crypto/salsa20.zig+11-8| ... | @@ -15,7 +15,10 @@ const Vector = std.meta.Vector; | ... | @@ -15,7 +15,10 @@ const Vector = std.meta.Vector; |
| 15 | const Poly1305 = crypto.onetimeauth.Poly1305; | 15 | const Poly1305 = crypto.onetimeauth.Poly1305; |
| 16 | const Blake2b = crypto.hash.blake2.Blake2b; | 16 | const Blake2b = crypto.hash.blake2.Blake2b; |
| 17 | const X25519 = crypto.dh.X25519; | 17 | const X25519 = crypto.dh.X25519; |
| 18 | const Error = crypto.Error; | 18 | |
| 19 | const AuthenticationError = crypto.errors.AuthenticationError; | ||
| 20 | const IdentityElementError = crypto.errors.IdentityElementError; | ||
| 21 | const WeakPublicKeyError = crypto.errors.WeakPublicKeyError; | ||
| 19 | 22 | ||
| 20 | const Salsa20VecImpl = struct { | 23 | const Salsa20VecImpl = struct { |
| 21 | const Lane = Vector(4, u32); | 24 | const Lane = Vector(4, u32); |
| ... | @@ -399,7 +402,7 @@ pub const XSalsa20Poly1305 = struct { | ... | @@ -399,7 +402,7 @@ pub const XSalsa20Poly1305 = struct { |
| 399 | /// ad: Associated Data | 402 | /// ad: Associated Data |
| 400 | /// npub: public nonce | 403 | /// npub: public nonce |
| 401 | /// k: private key | 404 | /// k: private key |
| 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 { | 405 | pub fn decrypt(m: []u8, c: []const u8, tag: [tag_length]u8, ad: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { |
| 403 | debug.assert(c.len == m.len); | 406 | debug.assert(c.len == m.len); |
| 404 | const extended = extend(k, npub); | 407 | const extended = extend(k, npub); |
| 405 | var block0 = [_]u8{0} ** 64; | 408 | var block0 = [_]u8{0} ** 64; |
| ... | @@ -447,7 +450,7 @@ pub const SecretBox = struct { | ... | @@ -447,7 +450,7 @@ pub const SecretBox = struct { |
| 447 | 450 | ||
| 448 | /// Verify and decrypt `c` using a nonce `npub` and a key `k`. | 451 | /// Verify and decrypt `c` using a nonce `npub` and a key `k`. |
| 449 | /// `m` must be exactly `tag_length` smaller than `c`, as `c` includes an authentication tag in addition to the encrypted message. | 452 | /// `m` must be exactly `tag_length` smaller than `c`, as `c` includes an authentication tag in addition to the encrypted message. |
| 450 | pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void { | 453 | pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void { |
| 451 | if (c.len < tag_length) { | 454 | if (c.len < tag_length) { |
| 452 | return error.AuthenticationFailed; | 455 | return error.AuthenticationFailed; |
| 453 | } | 456 | } |
| ... | @@ -482,20 +485,20 @@ pub const Box = struct { | ... | @@ -482,20 +485,20 @@ pub const Box = struct { |
| 482 | pub const KeyPair = X25519.KeyPair; | 485 | pub const KeyPair = X25519.KeyPair; |
| 483 | 486 | ||
| 484 | /// Compute a secret suitable for `secretbox` given a recipent's public key and a sender's secret key. | 487 | /// Compute a secret suitable for `secretbox` given a recipent's public key and a sender's secret key. |
| 485 | pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) Error![shared_length]u8 { | 488 | pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) (IdentityElementError || WeakPublicKeyError)![shared_length]u8 { |
| 486 | const p = try X25519.scalarmult(secret_key, public_key); | 489 | const p = try X25519.scalarmult(secret_key, public_key); |
| 487 | const zero = [_]u8{0} ** 16; | 490 | const zero = [_]u8{0} ** 16; |
| 488 | return Salsa20Impl.hsalsa20(zero, p); | 491 | return Salsa20Impl.hsalsa20(zero, p); |
| 489 | } | 492 | } |
| 490 | 493 | ||
| 491 | /// Encrypt and authenticate a message using a recipient's public key `public_key` and a sender's `secret_key`. | 494 | /// Encrypt and authenticate a message using a recipient's public key `public_key` and a sender's `secret_key`. |
| 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 { | 495 | pub fn seal(c: []u8, m: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) (IdentityElementError || WeakPublicKeyError)!void { |
| 493 | const shared_key = try createSharedSecret(public_key, secret_key); | 496 | const shared_key = try createSharedSecret(public_key, secret_key); |
| 494 | return SecretBox.seal(c, m, npub, shared_key); | 497 | return SecretBox.seal(c, m, npub, shared_key); |
| 495 | } | 498 | } |
| 496 | 499 | ||
| 497 | /// Verify and decrypt a message using a recipient's secret key `public_key` and a sender's `public_key`. | 500 | /// Verify and decrypt a message using a recipient's secret key `public_key` and a sender's `public_key`. |
| 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 { | 501 | pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) (IdentityElementError || WeakPublicKeyError || AuthenticationError)!void { |
| 499 | const shared_key = try createSharedSecret(public_key, secret_key); | 502 | const shared_key = try createSharedSecret(public_key, secret_key); |
| 500 | return SecretBox.open(m, c, npub, shared_key); | 503 | return SecretBox.open(m, c, npub, shared_key); |
| 501 | } | 504 | } |
| ... | @@ -528,7 +531,7 @@ pub const SealedBox = struct { | ... | @@ -528,7 +531,7 @@ pub const SealedBox = struct { |
| 528 | 531 | ||
| 529 | /// Encrypt a message `m` for a recipient whose public key is `public_key`. | 532 | /// Encrypt a message `m` for a recipient whose public key is `public_key`. |
| 530 | /// `c` must be `seal_length` bytes larger than `m`, so that the required metadata can be added. | 533 | /// `c` must be `seal_length` bytes larger than `m`, so that the required metadata can be added. |
| 531 | pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) Error!void { | 534 | pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) (WeakPublicKeyError || IdentityElementError)!void { |
| 532 | debug.assert(c.len == m.len + seal_length); | 535 | debug.assert(c.len == m.len + seal_length); |
| 533 | var ekp = try KeyPair.create(null); | 536 | var ekp = try KeyPair.create(null); |
| 534 | const nonce = createNonce(ekp.public_key, public_key); | 537 | const nonce = createNonce(ekp.public_key, public_key); |
| ... | @@ -539,7 +542,7 @@ pub const SealedBox = struct { | ... | @@ -539,7 +542,7 @@ pub const SealedBox = struct { |
| 539 | 542 | ||
| 540 | /// Decrypt a message using a key pair. | 543 | /// Decrypt a message using a key pair. |
| 541 | /// `m` must be exactly `seal_length` bytes smaller than `c`, as `c` also includes metadata. | 544 | /// `m` must be exactly `seal_length` bytes smaller than `c`, as `c` also includes metadata. |
| 542 | pub fn open(m: []u8, c: []const u8, keypair: KeyPair) Error!void { | 545 | pub fn open(m: []u8, c: []const u8, keypair: KeyPair) (IdentityElementError || WeakPublicKeyError || AuthenticationError)!void { |
| 543 | if (c.len < seal_length) { | 546 | if (c.len < seal_length) { |
| 544 | return error.AuthenticationFailed; | 547 | return error.AuthenticationFailed; |
| 545 | } | 548 | } |