Commit 10f2d62789
Changed files (19)
lib/std/crypto/25519/curve25519.zig
@@ -4,7 +4,11 @@
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std");
-const Error = std.crypto.Error;
+const crypto = std.crypto;
+
+const IdentityElementError = crypto.errors.IdentityElementError;
+const NonCanonicalError = crypto.errors.NonCanonicalError;
+const WeakPublicKeyError = crypto.errors.WeakPublicKeyError;
/// Group operations over Curve25519.
pub const Curve25519 = struct {
@@ -29,12 +33,12 @@ pub const Curve25519 = struct {
pub const basePoint = Curve25519{ .x = Fe.curve25519BasePoint };
/// Check that the encoding of a Curve25519 point is canonical.
- pub fn rejectNonCanonical(s: [32]u8) Error!void {
+ pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void {
return Fe.rejectNonCanonical(s, false);
}
/// Reject the neutral element.
- pub fn rejectIdentity(p: Curve25519) Error!void {
+ pub fn rejectIdentity(p: Curve25519) IdentityElementError!void {
if (p.x.isZero()) {
return error.IdentityElement;
}
@@ -45,7 +49,7 @@ pub const Curve25519 = struct {
return p.dbl().dbl().dbl();
}
- fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) Error!Curve25519 {
+ fn ladder(p: Curve25519, s: [32]u8, comptime bits: usize) IdentityElementError!Curve25519 {
var x1 = p.x;
var x2 = Fe.one;
var z2 = Fe.zero;
@@ -86,7 +90,7 @@ pub const Curve25519 = struct {
/// way to use Curve25519 for a DH operation.
/// Return error.IdentityElement if the resulting point is
/// the identity element.
- pub fn clampedMul(p: Curve25519, s: [32]u8) Error!Curve25519 {
+ pub fn clampedMul(p: Curve25519, s: [32]u8) IdentityElementError!Curve25519 {
var t: [32]u8 = s;
scalar.clamp(&t);
return try ladder(p, t, 255);
@@ -96,16 +100,16 @@ pub const Curve25519 = struct {
/// Return error.IdentityElement if the resulting point is
/// the identity element or error.WeakPublicKey if the public
/// key is a low-order point.
- pub fn mul(p: Curve25519, s: [32]u8) Error!Curve25519 {
+ pub fn mul(p: Curve25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Curve25519 {
const cofactor = [_]u8{8} ++ [_]u8{0} ** 31;
_ = ladder(p, cofactor, 4) catch |_| return error.WeakPublicKey;
return try ladder(p, s, 256);
}
/// Compute the Curve25519 equivalent to an Edwards25519 point.
- pub fn fromEdwards25519(p: std.crypto.ecc.Edwards25519) Error!Curve25519 {
+ pub fn fromEdwards25519(p: crypto.ecc.Edwards25519) IdentityElementError!Curve25519 {
try p.clearCofactor().rejectIdentity();
- const one = std.crypto.ecc.Edwards25519.Fe.one;
+ const one = crypto.ecc.Edwards25519.Fe.one;
const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd)
return Curve25519{ .x = x };
}
lib/std/crypto/25519/ed25519.zig
@@ -8,8 +8,15 @@ const crypto = std.crypto;
const debug = std.debug;
const fmt = std.fmt;
const mem = std.mem;
+
const Sha512 = crypto.hash.sha2.Sha512;
-const Error = crypto.Error;
+
+const EncodingError = crypto.errors.EncodingError;
+const IdentityElementError = crypto.errors.IdentityElementError;
+const NonCanonicalError = crypto.errors.NonCanonicalError;
+const SignatureVerificationError = crypto.errors.SignatureVerificationError;
+const KeyMismatchError = crypto.errors.KeyMismatchError;
+const WeakPublicKeyError = crypto.errors.WeakPublicKeyError;
/// Ed25519 (EdDSA) signatures.
pub const Ed25519 = struct {
@@ -41,7 +48,7 @@ pub const Ed25519 = struct {
///
/// For this reason, an EdDSA secret key is commonly called a seed,
/// from which the actual secret is derived.
- pub fn create(seed: ?[seed_length]u8) Error!KeyPair {
+ pub fn create(seed: ?[seed_length]u8) IdentityElementError!KeyPair {
const ss = seed orelse ss: {
var random_seed: [seed_length]u8 = undefined;
crypto.random.bytes(&random_seed);
@@ -51,7 +58,7 @@ pub const Ed25519 = struct {
var h = Sha512.init(.{});
h.update(&ss);
h.final(&az);
- const p = try Curve.basePoint.clampedMul(az[0..32].*);
+ const p = Curve.basePoint.clampedMul(az[0..32].*) catch return error.IdentityElement;
var sk: [secret_length]u8 = undefined;
mem.copy(u8, &sk, &ss);
const pk = p.toBytes();
@@ -72,7 +79,7 @@ pub const Ed25519 = struct {
/// Sign a message using a key pair, and optional random noise.
/// Having noise creates non-standard, non-deterministic signatures,
/// but has been proven to increase resilience against fault attacks.
- pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) Error![signature_length]u8 {
+ pub fn sign(msg: []const u8, key_pair: KeyPair, noise: ?[noise_length]u8) (IdentityElementError || WeakPublicKeyError || KeyMismatchError)![signature_length]u8 {
const seed = key_pair.secret_key[0..seed_length];
const public_key = key_pair.secret_key[seed_length..];
if (!mem.eql(u8, public_key, &key_pair.public_key)) {
@@ -113,7 +120,7 @@ pub const Ed25519 = struct {
/// Verify an Ed25519 signature given a message and a public key.
/// Returns error.SignatureVerificationFailed is the signature verification failed.
- pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) Error!void {
+ pub fn verify(sig: [signature_length]u8, msg: []const u8, public_key: [public_length]u8) (SignatureVerificationError || WeakPublicKeyError || EncodingError || NonCanonicalError || IdentityElementError)!void {
const r = sig[0..32];
const s = sig[32..64];
try Curve.scalar.rejectNonCanonical(s.*);
@@ -146,7 +153,7 @@ pub const Ed25519 = struct {
};
/// Verify several signatures in a single operation, much faster than verifying signatures one-by-one
- pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) Error!void {
+ pub fn verifyBatch(comptime count: usize, signature_batch: [count]BatchElement) (SignatureVerificationError || IdentityElementError || WeakPublicKeyError || EncodingError || NonCanonicalError)!void {
var r_batch: [count][32]u8 = undefined;
var s_batch: [count][32]u8 = undefined;
var a_batch: [count]Curve = undefined;
@@ -180,7 +187,7 @@ pub const Ed25519 = struct {
var z_batch: [count]Curve.scalar.CompressedScalar = undefined;
for (z_batch) |*z| {
- std.crypto.random.bytes(z[0..16]);
+ crypto.random.bytes(z[0..16]);
mem.set(u8, z[16..], 0);
}
@@ -233,8 +240,8 @@ test "ed25519 batch verification" {
const key_pair = try Ed25519.KeyPair.create(null);
var msg1: [32]u8 = undefined;
var msg2: [32]u8 = undefined;
- std.crypto.random.bytes(&msg1);
- std.crypto.random.bytes(&msg2);
+ crypto.random.bytes(&msg1);
+ crypto.random.bytes(&msg2);
const sig1 = try Ed25519.sign(&msg1, key_pair, null);
const sig2 = try Ed25519.sign(&msg2, key_pair, null);
var signature_batch = [_]Ed25519.BatchElement{
lib/std/crypto/25519/edwards25519.zig
@@ -4,10 +4,16 @@
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std");
+const crypto = std.crypto;
const debug = std.debug;
const fmt = std.fmt;
const mem = std.mem;
-const Error = std.crypto.Error;
+
+const EncodingError = crypto.errors.EncodingError;
+const IdentityElementError = crypto.errors.IdentityElementError;
+const NonCanonicalError = crypto.errors.NonCanonicalError;
+const NotSquareError = crypto.errors.NotSquareError;
+const WeakPublicKeyError = crypto.errors.WeakPublicKeyError;
/// Group operations over Edwards25519.
pub const Edwards25519 = struct {
@@ -26,7 +32,7 @@ pub const Edwards25519 = struct {
is_base: bool = false,
/// Decode an Edwards25519 point from its compressed (Y+sign) coordinates.
- pub fn fromBytes(s: [encoded_length]u8) Error!Edwards25519 {
+ pub fn fromBytes(s: [encoded_length]u8) EncodingError!Edwards25519 {
const z = Fe.one;
const y = Fe.fromBytes(s);
var u = y.sq();
@@ -56,7 +62,7 @@ pub const Edwards25519 = struct {
}
/// Check that the encoding of a point is canonical.
- pub fn rejectNonCanonical(s: [32]u8) Error!void {
+ pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void {
return Fe.rejectNonCanonical(s, true);
}
@@ -81,7 +87,7 @@ pub const Edwards25519 = struct {
const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
/// Reject the neutral element.
- pub fn rejectIdentity(p: Edwards25519) Error!void {
+ pub fn rejectIdentity(p: Edwards25519) IdentityElementError!void {
if (p.x.isZero()) {
return error.IdentityElement;
}
@@ -177,7 +183,7 @@ pub const Edwards25519 = struct {
// Based on real-world benchmarks, we only use this for multi-scalar multiplication.
// NAF could be useful to half the size of precomputation tables, but we intentionally
// avoid these to keep the standard library lightweight.
- fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 {
+ fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 {
std.debug.assert(vartime);
const e = nonAdjacentForm(s);
var q = Edwards25519.identityElement;
@@ -197,7 +203,7 @@ pub const Edwards25519 = struct {
}
// Scalar multiplication with a 4-bit window and the first 15 multiples.
- fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) Error!Edwards25519 {
+ fn pcMul16(pc: [16]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 {
var q = Edwards25519.identityElement;
var pos: usize = 252;
while (true) : (pos -= 4) {
@@ -233,12 +239,12 @@ pub const Edwards25519 = struct {
};
/// Multiply an Edwards25519 point by a scalar without clamping it.
- /// Return error.WeakPublicKey if the resulting point is
- /// the identity element.
- pub fn mul(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
+ /// Return error.WeakPublicKey if the base generates a small-order group,
+ /// and error.IdentityElement if the result is the identity element.
+ pub fn mul(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
const pc = if (p.is_base) basePointPc else pc: {
const xpc = precompute(p, 15);
- xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
+ xpc[4].rejectIdentity() catch return error.WeakPublicKey;
break :pc xpc;
};
return pcMul16(pc, s, false);
@@ -246,7 +252,7 @@ pub const Edwards25519 = struct {
/// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*
/// This can be used for signature verification.
- pub fn mulPublic(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
+ pub fn mulPublic(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
if (p.is_base) {
return pcMul16(basePointPc, s, true);
} else {
@@ -258,7 +264,7 @@ pub const Edwards25519 = struct {
/// Multiscalar multiplication *IN VARIABLE TIME* for public data
/// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually
- pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) Error!Edwards25519 {
+ pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
var pcs: [count][9]Edwards25519 = undefined;
for (ps) |p, i| {
if (p.is_base) {
@@ -297,14 +303,14 @@ pub const Edwards25519 = struct {
/// This is strongly recommended for DH operations.
/// Return error.WeakPublicKey if the resulting point is
/// the identity element.
- pub fn clampedMul(p: Edwards25519, s: [32]u8) Error!Edwards25519 {
+ pub fn clampedMul(p: Edwards25519, s: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
var t: [32]u8 = s;
scalar.clamp(&t);
return mul(p, t);
}
// montgomery -- recover y = sqrt(x^3 + A*x^2 + x)
- fn xmontToYmont(x: Fe) Error!Fe {
+ fn xmontToYmont(x: Fe) NotSquareError!Fe {
var x2 = x.sq();
const x3 = x.mul(x2);
x2 = x2.mul32(Fe.edwards25519a_32);
@@ -367,7 +373,7 @@ pub const Edwards25519 = struct {
fn stringToPoints(comptime n: usize, ctx: []const u8, s: []const u8) [n]Edwards25519 {
debug.assert(n <= 2);
- const H = std.crypto.hash.sha2.Sha512;
+ const H = crypto.hash.sha2.Sha512;
const h_l: usize = 48;
var xctx = ctx;
var hctx: [H.digest_length]u8 = undefined;
@@ -485,8 +491,8 @@ test "edwards25519 packing/unpacking" {
test "edwards25519 point addition/substraction" {
var s1: [32]u8 = undefined;
var s2: [32]u8 = undefined;
- std.crypto.random.bytes(&s1);
- std.crypto.random.bytes(&s2);
+ crypto.random.bytes(&s1);
+ crypto.random.bytes(&s2);
const p = try Edwards25519.basePoint.clampedMul(s1);
const q = try Edwards25519.basePoint.clampedMul(s2);
const r = p.add(q).add(q).sub(q).sub(q);
lib/std/crypto/25519/field.zig
@@ -4,9 +4,12 @@
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std");
+const crypto = std.crypto;
const readIntLittle = std.mem.readIntLittle;
const writeIntLittle = std.mem.writeIntLittle;
-const Error = std.crypto.Error;
+
+const NonCanonicalError = crypto.errors.NonCanonicalError;
+const NotSquareError = crypto.errors.NotSquareError;
pub const Fe = struct {
limbs: [5]u64,
@@ -113,7 +116,7 @@ pub const Fe = struct {
}
/// Reject non-canonical encodings of an element, possibly ignoring the top bit
- pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) Error!void {
+ pub fn rejectNonCanonical(s: [32]u8, comptime ignore_extra_bit: bool) NonCanonicalError!void {
var c: u16 = (s[31] & 0x7f) ^ 0x7f;
comptime var i = 30;
inline while (i > 0) : (i -= 1) {
@@ -413,7 +416,7 @@ pub const Fe = struct {
}
/// Compute the square root of `x2`, returning `error.NotSquare` if `x2` was not a square
- pub fn sqrt(x2: Fe) Error!Fe {
+ pub fn sqrt(x2: Fe) NotSquareError!Fe {
var x2_copy = x2;
const x = x2.uncheckedSqrt();
const check = x.sq().sub(x2_copy);
lib/std/crypto/25519/ristretto255.zig
@@ -5,7 +5,11 @@
// and substantial portions of the software.
const std = @import("std");
const fmt = std.fmt;
-const Error = std.crypto.Error;
+
+const EncodingError = std.crypto.errors.EncodingError;
+const IdentityElementError = std.crypto.errors.IdentityElementError;
+const NonCanonicalError = std.crypto.errors.NonCanonicalError;
+const WeakPublicKeyError = std.crypto.errors.WeakPublicKeyError;
/// Group operations over Edwards25519.
pub const Ristretto255 = struct {
@@ -35,7 +39,7 @@ pub const Ristretto255 = struct {
return .{ .ratio_is_square = @boolToInt(has_m_root) | @boolToInt(has_p_root), .root = x.abs() };
}
- fn rejectNonCanonical(s: [encoded_length]u8) Error!void {
+ fn rejectNonCanonical(s: [encoded_length]u8) NonCanonicalError!void {
if ((s[0] & 1) != 0) {
return error.NonCanonical;
}
@@ -43,7 +47,7 @@ pub const Ristretto255 = struct {
}
/// Reject the neutral element.
- pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) Error!void {
+ pub fn rejectIdentity(p: Ristretto255) callconv(.Inline) IdentityElementError!void {
return p.p.rejectIdentity();
}
@@ -51,7 +55,7 @@ pub const Ristretto255 = struct {
pub const basePoint = Ristretto255{ .p = Curve.basePoint };
/// Decode a Ristretto255 representative.
- pub fn fromBytes(s: [encoded_length]u8) Error!Ristretto255 {
+ pub fn fromBytes(s: [encoded_length]u8) (NonCanonicalError || EncodingError)!Ristretto255 {
try rejectNonCanonical(s);
const s_ = Fe.fromBytes(s);
const ss = s_.sq(); // s^2
@@ -154,7 +158,7 @@ pub const Ristretto255 = struct {
/// Multiply a Ristretto255 element with a scalar.
/// Return error.WeakPublicKey if the resulting element is
/// the identity element.
- pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) Error!Ristretto255 {
+ pub fn mul(p: Ristretto255, s: [encoded_length]u8) callconv(.Inline) (IdentityElementError || WeakPublicKeyError)!Ristretto255 {
return Ristretto255{ .p = try p.p.mul(s) };
}
lib/std/crypto/25519/scalar.zig
@@ -5,7 +5,8 @@
// and substantial portions of the software.
const std = @import("std");
const mem = std.mem;
-const Error = std.crypto.Error;
+
+const NonCanonicalError = std.crypto.errors.NonCanonicalError;
/// 2^252 + 27742317777372353535851937790883648493
pub const field_size = [32]u8{
@@ -19,7 +20,7 @@ pub const CompressedScalar = [32]u8;
pub const zero = [_]u8{0} ** 32;
/// Reject a scalar whose encoding is not canonical.
-pub fn rejectNonCanonical(s: [32]u8) Error!void {
+pub fn rejectNonCanonical(s: [32]u8) NonCanonicalError!void {
var c: u8 = 0;
var n: u8 = 1;
var i: usize = 31;
lib/std/crypto/25519/x25519.zig
@@ -9,7 +9,10 @@ const mem = std.mem;
const fmt = std.fmt;
const Sha512 = crypto.hash.sha2.Sha512;
-const Error = crypto.Error;
+
+const EncodingError = crypto.errors.EncodingError;
+const IdentityElementError = crypto.errors.IdentityElementError;
+const WeakPublicKeyError = crypto.errors.WeakPublicKeyError;
/// X25519 DH function.
pub const X25519 = struct {
@@ -32,7 +35,7 @@ pub const X25519 = struct {
secret_key: [secret_length]u8,
/// Create a new key pair using an optional seed.
- pub fn create(seed: ?[seed_length]u8) Error!KeyPair {
+ pub fn create(seed: ?[seed_length]u8) IdentityElementError!KeyPair {
const sk = seed orelse sk: {
var random_seed: [seed_length]u8 = undefined;
crypto.random.bytes(&random_seed);
@@ -45,7 +48,7 @@ pub const X25519 = struct {
}
/// Create a key pair from an Ed25519 key pair
- pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) Error!KeyPair {
+ pub fn fromEd25519(ed25519_key_pair: crypto.sign.Ed25519.KeyPair) (IdentityElementError || EncodingError)!KeyPair {
const seed = ed25519_key_pair.secret_key[0..32];
var az: [Sha512.digest_length]u8 = undefined;
Sha512.hash(seed, &az, .{});
@@ -60,13 +63,13 @@ pub const X25519 = struct {
};
/// Compute the public key for a given private key.
- pub fn recoverPublicKey(secret_key: [secret_length]u8) Error![public_length]u8 {
+ pub fn recoverPublicKey(secret_key: [secret_length]u8) IdentityElementError![public_length]u8 {
const q = try Curve.basePoint.clampedMul(secret_key);
return q.toBytes();
}
/// Compute the X25519 equivalent to an Ed25519 public eky.
- pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) Error![public_length]u8 {
+ pub fn publicKeyFromEd25519(ed25519_public_key: [crypto.sign.Ed25519.public_length]u8) (IdentityElementError || EncodingError)![public_length]u8 {
const pk_ed = try crypto.ecc.Edwards25519.fromBytes(ed25519_public_key);
const pk = try Curve.fromEdwards25519(pk_ed);
return pk.toBytes();
@@ -75,7 +78,7 @@ pub const X25519 = struct {
/// Compute the scalar product of a public key and a secret scalar.
/// Note that the output should not be used as a shared secret without
/// hashing it first.
- pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) Error![shared_length]u8 {
+ pub fn scalarmult(secret_key: [secret_length]u8, public_key: [public_length]u8) IdentityElementError![shared_length]u8 {
const q = try Curve.fromBytes(public_key).clampedMul(secret_key);
return q.toBytes();
}
lib/std/crypto/aegis.zig
@@ -8,7 +8,7 @@ const std = @import("std");
const mem = std.mem;
const assert = std.debug.assert;
const AesBlock = std.crypto.core.aes.Block;
-const Error = std.crypto.Error;
+const AuthenticationError = std.crypto.errors.AuthenticationError;
const State128L = struct {
blocks: [8]AesBlock,
@@ -137,7 +137,7 @@ pub const Aegis128L = struct {
/// ad: Associated Data
/// npub: public nonce
/// k: private key
- 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 {
+ 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 {
assert(c.len == m.len);
var state = State128L.init(key, npub);
var src: [32]u8 align(16) = undefined;
@@ -299,7 +299,7 @@ pub const Aegis256 = struct {
/// ad: Associated Data
/// npub: public nonce
/// k: private key
- 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 {
+ 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 {
assert(c.len == m.len);
var state = State256.init(key, npub);
var src: [16]u8 align(16) = undefined;
lib/std/crypto/aes_gcm.zig
@@ -12,7 +12,7 @@ const debug = std.debug;
const Ghash = std.crypto.onetimeauth.Ghash;
const mem = std.mem;
const modes = crypto.core.modes;
-const Error = crypto.Error;
+const AuthenticationError = crypto.errors.AuthenticationError;
pub const Aes128Gcm = AesGcm(crypto.core.aes.Aes128);
pub const Aes256Gcm = AesGcm(crypto.core.aes.Aes256);
@@ -60,7 +60,7 @@ fn AesGcm(comptime Aes: anytype) type {
}
}
- 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 {
+ 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 {
assert(c.len == m.len);
const aes = Aes.initEnc(key);
lib/std/crypto/aes_ocb.zig
@@ -10,7 +10,7 @@ const aes = crypto.core.aes;
const assert = std.debug.assert;
const math = std.math;
const mem = std.mem;
-const Error = crypto.Error;
+const AuthenticationError = crypto.errors.AuthenticationError;
pub const Aes128Ocb = AesOcb(aes.Aes128);
pub const Aes256Ocb = AesOcb(aes.Aes256);
@@ -179,7 +179,7 @@ fn AesOcb(comptime Aes: anytype) type {
/// ad: Associated Data
/// npub: public nonce
/// k: secret key
- 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 {
+ 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 {
assert(c.len == m.len);
const aes_enc_ctx = Aes.initEnc(key);
lib/std/crypto/bcrypt.zig
@@ -12,7 +12,8 @@ const mem = std.mem;
const debug = std.debug;
const testing = std.testing;
const utils = crypto.utils;
-const Error = crypto.Error;
+const EncodingError = crypto.errors.EncodingError;
+const PasswordVerificationError = crypto.errors.PasswordVerificationError;
const salt_length: usize = 16;
const salt_str_length: usize = 22;
@@ -179,7 +180,7 @@ const Codec = struct {
debug.assert(j == b64.len);
}
- fn decode(bin: []u8, b64: []const u8) Error!void {
+ fn decode(bin: []u8, b64: []const u8) EncodingError!void {
var i: usize = 0;
var j: usize = 0;
while (j < bin.len) {
@@ -204,7 +205,7 @@ const Codec = struct {
}
};
-fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) Error![hash_length]u8 {
+fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8) ![hash_length]u8 {
var state = State{};
var password_buf: [73]u8 = undefined;
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)
/// IMPORTANT: by design, bcrypt silently truncates passwords to 72 bytes.
/// If this is an issue for your application, hash the password first using a function such as SHA-512,
/// and then use the resulting hash as the password parameter for bcrypt.
-pub fn strHash(password: []const u8, rounds_log: u6) Error![hash_length]u8 {
+pub fn strHash(password: []const u8, rounds_log: u6) ![hash_length]u8 {
var salt: [salt_length]u8 = undefined;
crypto.random.bytes(&salt);
return strHashInternal(password, rounds_log, salt);
}
/// Verify that a previously computed hash is valid for a given password.
-pub fn strVerify(h: [hash_length]u8, password: []const u8) Error!void {
+pub fn strVerify(h: [hash_length]u8, password: []const u8) (EncodingError || PasswordVerificationError)!void {
if (!mem.eql(u8, "$2", h[0..2])) return error.InvalidEncoding;
if (h[3] != '$' or h[6] != '$') return error.InvalidEncoding;
const rounds_log_str = h[4..][0..2];
lib/std/crypto/chacha20.zig
@@ -13,7 +13,7 @@ const testing = std.testing;
const maxInt = math.maxInt;
const Vector = std.meta.Vector;
const Poly1305 = std.crypto.onetimeauth.Poly1305;
-const Error = std.crypto.Error;
+const AuthenticationError = std.crypto.errors.AuthenticationError;
/// IETF-variant of the ChaCha20 stream cipher, as designed for TLS.
pub const ChaCha20IETF = ChaChaIETF(20);
@@ -521,7 +521,7 @@ fn ChaChaPoly1305(comptime rounds_nb: usize) type {
/// npub: public nonce
/// k: private key
/// NOTE: the check of the authentication tag is currently not done in constant time
- 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 {
+ 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 {
assert(c.len == m.len);
var polyKey = [_]u8{0} ** 32;
@@ -583,7 +583,7 @@ fn XChaChaPoly1305(comptime rounds_nb: usize) type {
/// ad: Associated Data
/// npub: public nonce
/// k: private key
- 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 {
+ 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 {
const extended = extend(k, npub, rounds_nb);
return ChaChaPoly1305(rounds_nb).decrypt(m, c, tag, ad, extended.nonce, extended.key);
}
lib/std/crypto/error.zig
@@ -1,34 +0,0 @@
-pub const Error = error{
- /// MAC verification failed - The tag doesn't verify for the given ciphertext and secret key
- AuthenticationFailed,
-
- /// The requested output length is too long for the chosen algorithm
- OutputTooLong,
-
- /// Finite field operation returned the identity element
- IdentityElement,
-
- /// Encoded input cannot be decoded
- InvalidEncoding,
-
- /// The signature does't verify for the given message and public key
- SignatureVerificationFailed,
-
- /// Both a public and secret key have been provided, but they are incompatible
- KeyMismatch,
-
- /// Encoded input is not in canonical form
- NonCanonical,
-
- /// Square root has no solutions
- NotSquare,
-
- /// Verification string doesn't match the provided password and parameters
- PasswordVerificationFailed,
-
- /// Parameters would be insecure to use
- WeakParameters,
-
- /// Public key would be insecure to use
- WeakPublicKey,
-};
lib/std/crypto/errors.zig
@@ -0,0 +1,35 @@
+/// MAC verification failed - The tag doesn't verify for the given ciphertext and secret key
+pub const AuthenticationError = error{AuthenticationFailed};
+
+/// The requested output length is too long for the chosen algorithm
+pub const OutputTooLongError = error{OutputTooLong};
+
+/// Finite field operation returned the identity element
+pub const IdentityElementError = error{IdentityElement};
+
+/// Encoded input cannot be decoded
+pub const EncodingError = error{InvalidEncoding};
+
+/// The signature does't verify for the given message and public key
+pub const SignatureVerificationError = error{SignatureVerificationFailed};
+
+/// Both a public and secret key have been provided, but they are incompatible
+pub const KeyMismatchError = error{KeyMismatch};
+
+/// Encoded input is not in canonical form
+pub const NonCanonicalError = error{NonCanonical};
+
+/// Square root has no solutions
+pub const NotSquareError = error{NotSquare};
+
+/// Verification string doesn't match the provided password and parameters
+pub const PasswordVerificationError = error{PasswordVerificationFailed};
+
+/// Parameters would be insecure to use
+pub const WeakParametersError = error{WeakParameters};
+
+/// Public key would be insecure to use
+pub const WeakPublicKeyError = error{WeakPublicKey};
+
+/// Any error related to cryptography operations
+pub const Error = AuthenticationError || OutputTooLongError || IdentityElementError || EncodingError || SignatureVerificationError || KeyMismatchError || NonCanonicalError || NotSquareError || PasswordVerificationError || WeakParametersError || WeakPublicKeyError;
lib/std/crypto/gimli.zig
@@ -20,7 +20,7 @@ const assert = std.debug.assert;
const testing = std.testing;
const htest = @import("test.zig");
const Vector = std.meta.Vector;
-const Error = std.crypto.Error;
+const AuthenticationError = std.crypto.errors.AuthenticationError;
pub const State = struct {
pub const BLOCKBYTES = 48;
@@ -393,7 +393,7 @@ pub const Aead = struct {
/// npub: public nonce
/// k: private key
/// NOTE: the check of the authentication tag is currently not done in constant time
- 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 {
+ 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 {
assert(c.len == m.len);
var state = Aead.init(ad, npub, k);
lib/std/crypto/isap.zig
@@ -3,7 +3,7 @@ const debug = std.debug;
const mem = std.mem;
const math = std.math;
const testing = std.testing;
-const Error = std.crypto.Error;
+const AuthenticationError = std.crypto.errors.AuthenticationError;
/// ISAPv2 is an authenticated encryption system hardened against side channels and fault attacks.
/// 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 {
tag.* = mac(c, ad, npub, key);
}
- 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 {
+ 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 {
var computed_tag = mac(c, ad, npub, key);
var acc: u8 = 0;
for (computed_tag) |_, j| {
lib/std/crypto/pbkdf2.zig
@@ -7,7 +7,8 @@
const std = @import("std");
const mem = std.mem;
const maxInt = std.math.maxInt;
-const Error = std.crypto.Error;
+const OutputTooLongError = std.crypto.errors.OutputTooLongError;
+const WeakParametersError = std.crypto.errors.WeakParametersError;
// RFC 2898 Section 5.2
//
@@ -55,7 +56,7 @@ const Error = std.crypto.Error;
/// the dk. It is common to tune this parameter to achieve approximately 100ms.
///
/// Prf: Pseudo-random function to use. A common choice is `std.crypto.auth.hmac.HmacSha256`.
-pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) Error!void {
+pub fn pbkdf2(dk: []u8, password: []const u8, salt: []const u8, rounds: u32, comptime Prf: type) (WeakParametersError || OutputTooLongError)!void {
if (rounds < 1) return error.WeakParameters;
const dk_len = dk.len;
lib/std/crypto/salsa20.zig
@@ -15,7 +15,10 @@ const Vector = std.meta.Vector;
const Poly1305 = crypto.onetimeauth.Poly1305;
const Blake2b = crypto.hash.blake2.Blake2b;
const X25519 = crypto.dh.X25519;
-const Error = crypto.Error;
+
+const AuthenticationError = crypto.errors.AuthenticationError;
+const IdentityElementError = crypto.errors.IdentityElementError;
+const WeakPublicKeyError = crypto.errors.WeakPublicKeyError;
const Salsa20VecImpl = struct {
const Lane = Vector(4, u32);
@@ -399,7 +402,7 @@ pub const XSalsa20Poly1305 = struct {
/// ad: Associated Data
/// npub: public nonce
/// k: private key
- 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 {
+ 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 {
debug.assert(c.len == m.len);
const extended = extend(k, npub);
var block0 = [_]u8{0} ** 64;
@@ -447,7 +450,7 @@ pub const SecretBox = struct {
/// Verify and decrypt `c` using a nonce `npub` and a key `k`.
/// `m` must be exactly `tag_length` smaller than `c`, as `c` includes an authentication tag in addition to the encrypted message.
- pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) Error!void {
+ pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, k: [key_length]u8) AuthenticationError!void {
if (c.len < tag_length) {
return error.AuthenticationFailed;
}
@@ -482,20 +485,20 @@ pub const Box = struct {
pub const KeyPair = X25519.KeyPair;
/// Compute a secret suitable for `secretbox` given a recipent's public key and a sender's secret key.
- pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) Error![shared_length]u8 {
+ pub fn createSharedSecret(public_key: [public_length]u8, secret_key: [secret_length]u8) (IdentityElementError || WeakPublicKeyError)![shared_length]u8 {
const p = try X25519.scalarmult(secret_key, public_key);
const zero = [_]u8{0} ** 16;
return Salsa20Impl.hsalsa20(zero, p);
}
/// Encrypt and authenticate a message using a recipient's public key `public_key` and a sender's `secret_key`.
- pub fn seal(c: []u8, m: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) Error!void {
+ 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 {
const shared_key = try createSharedSecret(public_key, secret_key);
return SecretBox.seal(c, m, npub, shared_key);
}
/// Verify and decrypt a message using a recipient's secret key `public_key` and a sender's `public_key`.
- pub fn open(m: []u8, c: []const u8, npub: [nonce_length]u8, public_key: [public_length]u8, secret_key: [secret_length]u8) Error!void {
+ 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 {
const shared_key = try createSharedSecret(public_key, secret_key);
return SecretBox.open(m, c, npub, shared_key);
}
@@ -528,7 +531,7 @@ pub const SealedBox = struct {
/// Encrypt a message `m` for a recipient whose public key is `public_key`.
/// `c` must be `seal_length` bytes larger than `m`, so that the required metadata can be added.
- pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) Error!void {
+ pub fn seal(c: []u8, m: []const u8, public_key: [public_length]u8) (WeakPublicKeyError || IdentityElementError)!void {
debug.assert(c.len == m.len + seal_length);
var ekp = try KeyPair.create(null);
const nonce = createNonce(ekp.public_key, public_key);
@@ -539,7 +542,7 @@ pub const SealedBox = struct {
/// Decrypt a message using a key pair.
/// `m` must be exactly `seal_length` bytes smaller than `c`, as `c` also includes metadata.
- pub fn open(m: []u8, c: []const u8, keypair: KeyPair) Error!void {
+ pub fn open(m: []u8, c: []const u8, keypair: KeyPair) (IdentityElementError || WeakPublicKeyError || AuthenticationError)!void {
if (c.len < seal_length) {
return error.AuthenticationFailed;
}
lib/std/crypto.zig
@@ -154,7 +154,7 @@ pub const random = &@import("crypto/tlcsprng.zig").interface;
const std = @import("std.zig");
-pub const Error = @import("crypto/error.zig").Error;
+pub const errors = @import("crypto/errors.zig");
test "crypto" {
const please_windows_dont_oom = std.Target.current.os.tag == .windows;