Compare commits
No commits in common. "d7139c6ce87a184696a4735ff6b5b0eec34015c6" and "e594fab52f33786f9a51483ae26951fde1d4dcfe" have entirely different histories.
d7139c6ce8
...
e594fab52f
4 changed files with 61 additions and 147 deletions
|
|
@ -1,14 +1,14 @@
|
||||||
///////////////// Imports
|
///////////////// Imports
|
||||||
//
|
//
|
||||||
|
|
||||||
pub const Aes = @import("crypto/aes.zig");
|
const AES = @import("crypto/aes.zig");
|
||||||
pub const Ed25519 = @import("crypto/ed25519.zig");
|
const ED25519 = @import("crypto/ed25519.zig");
|
||||||
pub const Hkdf = @import("crypto/hkdf.zig");
|
const HKDF = @import("crypto/hkdf.zig");
|
||||||
pub const Hmac = @import("crypto/hmac.zig");
|
const HMAC = @import("crypto/hmac.zig");
|
||||||
pub const Sha256 = @import("crypto/sha256.zig");
|
const SHA256 = @import("crypto/sha256.zig");
|
||||||
pub const Sha512 = @import("crypto/sha512.zig");
|
const SHA512 = @import("crypto/sha512.zig");
|
||||||
pub const X25519= @import("crypto/x25519.zig");
|
const X25519= @import("crypto/x25519.zig");
|
||||||
pub const Random = @import("crypto/random.zig");
|
const RANDOM = @import("crypto/random.zig");
|
||||||
|
|
||||||
|
|
||||||
///////////////// Errors
|
///////////////// Errors
|
||||||
|
|
@ -25,25 +25,25 @@ pub const CryptoError = error {
|
||||||
//
|
//
|
||||||
|
|
||||||
pub const PartialEngine = struct {
|
pub const PartialEngine = struct {
|
||||||
aes_cbc256: ? Aes.CBC256.Implementation = null,
|
aes_cbc256: ? AES.CBC256.Implementation = null,
|
||||||
ed25519: ? Ed25519.Implementation = null,
|
ed25519: ? ED25519.Implementation = null,
|
||||||
hkdf: ? Hkdf.Implementation = null,
|
hkdf: ? HKDF.Implementation = null,
|
||||||
hmac: ? Hmac.Implementation = null,
|
hmac: ? HMAC.Implementation = null,
|
||||||
sha256: ? Sha256.Implementation = null,
|
sha256: ? SHA256.Implementation = null,
|
||||||
sha512: ? Sha512.Implementation = null,
|
sha512: ? SHA512.Implementation = null,
|
||||||
x25519: ? X25519.Implementation = null,
|
x25519: ? X25519.Implementation = null,
|
||||||
random: ? Random.Implementation = null,
|
random: ? RANDOM.Implementation = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Engine = struct {
|
pub const Engine = struct {
|
||||||
aes_cbc256: Aes.CBC256.Implementation,
|
aes_cbc256: AES.CBC256.Implementation,
|
||||||
ed25519: Ed25519.Implementation,
|
ed25519: ED25519.Implementation,
|
||||||
hkdf: Hkdf.Implementation,
|
hkdf: HKDF.Implementation,
|
||||||
hmac: Hmac.Implementation,
|
hmac: HMAC.Implementation,
|
||||||
sha256: Sha256.Implementation,
|
sha256: SHA256.Implementation,
|
||||||
sha512: Sha512.Implementation,
|
sha512: SHA512.Implementation,
|
||||||
x25519: X25519.Implementation,
|
x25519: X25519.Implementation,
|
||||||
random: Random.Implementation,
|
random: RANDOM.Implementation,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -56,14 +56,14 @@ pub const Engine = struct {
|
||||||
pub fn resolveEngine(comptime provider: PartialEngine) Engine {
|
pub fn resolveEngine(comptime provider: PartialEngine) Engine {
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.aes_cbc256 = provider.aes_cbc256 orelse Aes.CBC256.defaultImplementation,
|
.aes_cbc256 = provider.aes_cbc256 orelse AES.CBC256.defaultImplementation,
|
||||||
.ed25519 = provider.ed25519 orelse Ed25519.defaultImplementation,
|
.ed25519 = provider.ed25519 orelse ED25519.defaultImplementation,
|
||||||
.hkdf = provider.hkdf orelse Hkdf.defaultImplementation,
|
.hkdf = provider.hkdf orelse HKDF.defaultImplementation,
|
||||||
.hmac = provider.hmac orelse Hmac.defaultImplementation,
|
.hmac = provider.hmac orelse HMAC.defaultImplementation,
|
||||||
.sha256 = provider.sha256 orelse Sha256.defaultImplementation,
|
.sha256 = provider.sha256 orelse SHA256.defaultImplementation,
|
||||||
.sha512 = provider.sha512 orelse Sha512.defaultImplementation,
|
.sha512 = provider.sha512 orelse SHA512.defaultImplementation,
|
||||||
.x25519 = provider.x25519 orelse X25519.defaultImplementation,
|
.x25519 = provider.x25519 orelse X25519.defaultImplementation,
|
||||||
.random = provider.random orelse Random.defaultImplementation,
|
.random = provider.random orelse RANDOM.defaultImplementation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,42 +2,40 @@
|
||||||
const CryptoError = @import("../crypto.zig").CryptoError;
|
const CryptoError = @import("../crypto.zig").CryptoError;
|
||||||
// Constants and default implementation
|
// Constants and default implementation
|
||||||
const Ed25519 = @import("std").crypto.sign.Ed25519;
|
const Ed25519 = @import("std").crypto.sign.Ed25519;
|
||||||
const secureZero = @import("std").crypto.secureZero;
|
|
||||||
// Random number generation
|
// Random number generation
|
||||||
const rngProvider = @import("random.zig").Implementation;
|
const rngProvider = @import("random.zig").Implementation;
|
||||||
|
|
||||||
// Keypair type
|
pub const secret_key_size: comptime_int = Ed25519.SecretKey.encoded_length;
|
||||||
pub const KeyPair = Ed25519.KeyPair;
|
pub const public_key_size: comptime_int = Ed25519.PublicKey.encoded_length;
|
||||||
|
pub const signature_size : comptime_int = Ed25519.Signature.encoded_length;
|
||||||
pub const secret_key_length: comptime_int = Ed25519.SecretKey.encoded_length;
|
|
||||||
pub const public_key_length: comptime_int = Ed25519.PublicKey.encoded_length;
|
|
||||||
pub const signature_length : comptime_int = Ed25519.Signature.encoded_length;
|
|
||||||
pub const seed_length : comptime_int = Ed25519.Signature.encoded_length;
|
|
||||||
|
|
||||||
pub const Implementation = struct {
|
pub const Implementation = struct {
|
||||||
|
|
||||||
generateKeys: *const fn (destination: *KeyPair, rng: rngProvider) CryptoError!void,
|
generateKeys: *const fn (pubkey_buffer: *[public_key_size]u8, privkey_buffer: *[secret_key_size]u8, rng: rngProvider) CryptoError!void,
|
||||||
sign: *const fn (key: *const [secret_key_length]u8, data: []const u8, signature_out: *const [signature_length]u8) CryptoError!void,
|
sign: *const fn (key: *const [secret_key_size]u8, data: []const u8, signature_out: *const [signature_size]u8) CryptoError!void,
|
||||||
verify: *const fn (key: *const [public_key_length]u8, signature: *const [signature_length]u8, data: []const u8) CryptoError!void,
|
verify: *const fn (key: *const [public_key_size]u8, signature: *const [signature_size]u8, data: []const u8) CryptoError!void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub fn generateKeys (destination: *KeyPair, rng: rngProvider) !void {
|
pub fn generateKeys(pubkey_buffer: *[public_key_size]u8, privkey_buffer: *[secret_key_size]u8, rng: rngProvider) !void {
|
||||||
|
|
||||||
var seed_buffer: [KeyPair.seed_length]u8 = undefined;
|
var seed_buffer: [Ed25519.KeyPair.seed_length]u8 = undefined;
|
||||||
defer secureZero(u8, &seed_buffer);
|
|
||||||
rng.generate(&seed_buffer);
|
rng.generate(&seed_buffer);
|
||||||
destination.* = KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
const keypair: Ed25519.KeyPair = Ed25519.KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
||||||
|
|
||||||
|
|
||||||
|
@memcpy(pubkey_buffer[0..public_key_size], &keypair.public_key.bytes);
|
||||||
|
@memcpy(privkey_buffer[0..secret_key_size], &keypair.secret_key.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sign (key: *const [secret_key_length]u8, data: []const u8, signature_out: *const [signature_length]u8) !void {
|
pub fn sign(key: *const [secret_key_size]u8, data: []const u8, signature_out: *const [signature_size]u8) !void {
|
||||||
_ = key;
|
_ = key;
|
||||||
_ = data;
|
_ = data;
|
||||||
_ = signature_out;
|
_ = signature_out;
|
||||||
return CryptoError.NotImplemented;
|
return CryptoError.NotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify (key: *const [public_key_length]u8, signature: *const [signature_length]u8, data: []const u8) !void {
|
pub fn verify(key: *const [public_key_size]u8, signature: *const [signature_size]u8, data: []const u8) !void {
|
||||||
// TODO maybe find a more efficient way to do that (excessive copies)
|
// TODO maybe find a more efficient way to do that (excessive copies)
|
||||||
const sig = Ed25519.Signature.fromBytes(signature.*);
|
const sig = Ed25519.Signature.fromBytes(signature.*);
|
||||||
const pubkey = Ed25519.PublicKey.fromBytes(key.*) catch return CryptoError.InvalidKey;
|
const pubkey = Ed25519.PublicKey.fromBytes(key.*) catch return CryptoError.InvalidKey;
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,13 @@
|
||||||
// Errors
|
//TODO
|
||||||
const CryptoError = @import("../crypto.zig").CryptoError;
|
|
||||||
// Constants and default implementation
|
|
||||||
const X25519 = @import("std").crypto.dh.X25519;
|
|
||||||
const Ed25519 = @import("std").crypto.sign.Ed25519;
|
|
||||||
const secureZero = @import("std").crypto.secureZero;
|
|
||||||
// Random number generation
|
|
||||||
const rngProvider = @import("random.zig").Implementation;
|
|
||||||
|
|
||||||
// Keypair type
|
const X25519 = @import("std").std.crypto.dh.X25519;
|
||||||
pub const KeyPair = X25519.KeyPair;
|
|
||||||
|
|
||||||
pub const secret_key_length: comptime_int = X25519.secret_length;
|
|
||||||
pub const public_key_length: comptime_int = X25519.public_length;
|
|
||||||
pub const seed_length: comptime_int = X25519.seed_length;
|
|
||||||
|
|
||||||
pub const Implementation = struct {
|
pub const Implementation = struct {
|
||||||
|
|
||||||
generateKeys: *const fn (destination: *KeyPair, rng: rngProvider) CryptoError!void,
|
|
||||||
fromEd25519: *const fn (ed25519_keypair: *Ed25519.KeyPair, x25519_keypair: *KeyPair) CryptoError!void,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn generateKeys (destination: *KeyPair, rng: rngProvider) !void {
|
|
||||||
|
|
||||||
var seed_buffer: [seed_length]u8 = undefined;
|
|
||||||
defer secureZero(u8, &seed_buffer);
|
|
||||||
rng.generate(&seed_buffer);
|
|
||||||
destination.* = X25519.KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fromEd25519 (ed25519_keypair: *Ed25519.KeyPair, x25519_keypair: *KeyPair) CryptoError!void {
|
|
||||||
x25519_keypair.* = X25519.KeyPair.fromEd25519(ed25519_keypair.*) catch return CryptoError.InvalidKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const defaultImplementation: Implementation = .{
|
pub const defaultImplementation: Implementation = .{
|
||||||
.generateKeys = generateKeys,
|
|
||||||
.fromEd25519 = fromEd25519,
|
// One problem, it uses the zig's io module, which is not supported yet as it depends on the target OS
|
||||||
|
// It may need a custom implementation or some other library
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
///////////////// Imports
|
///////////////// Imports
|
||||||
//
|
//
|
||||||
|
|
||||||
const Crypto = @import("crypto.zig");
|
const CryptoEngine = @import("crypto.zig").Engine;
|
||||||
|
|
||||||
///////////////// Constants
|
///////////////// Constants
|
||||||
//
|
//
|
||||||
|
|
@ -13,38 +13,25 @@ const Crypto = @import("crypto.zig");
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
pub fn resolveIdentity(comptime crypto_engine: Crypto.Engine) type {
|
pub fn Identity(comptime crypto_engine: CryptoEngine) type {
|
||||||
|
_ = crypto_engine;
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
//////// Fields
|
//////// Fields
|
||||||
//
|
//
|
||||||
keys: Crypto.Ed25519.KeyPair,
|
publicKey: []const u8,
|
||||||
signatureKeys: Crypto.X25519.KeyPair,
|
privateKey: []const u8,
|
||||||
hash: [Crypto.Sha256.hash_len]u8,
|
signature: []const u8,
|
||||||
|
hash: []const u8,
|
||||||
|
|
||||||
//////// Functions
|
//////// Functions
|
||||||
//
|
//
|
||||||
pub fn new() !Self {
|
pub fn generate() !Identity {
|
||||||
const result: Self = undefined;
|
return .{
|
||||||
crypto_engine.ed25519.generateKeys(result.keys, crypto_engine.random);
|
// .privateKey = crypto_engine.ed25519.generateKey(...),
|
||||||
crypto_engine.x25519.fromEd25519(result.keys, result.signatureKeys, crypto_engine.random);
|
// .signature = crypto_engine.x25519.
|
||||||
result.update_hash();
|
};
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate(self: *Self) !void {
|
|
||||||
try crypto_engine.ed25519.generateKeys(&self.keys, crypto_engine.random);
|
|
||||||
try crypto_engine.x25519.fromEd25519(&self.keys, &self.signatureKeys);
|
|
||||||
self.update_hash();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_hash(self: *Self) void {
|
|
||||||
//WARNING PUBLIC KEY SHOULD BE TRUNCATED
|
|
||||||
// We should define the truncated hash length somewhere
|
|
||||||
crypto_engine.sha256.hash(&self.keys.public_key.bytes, &self.hash);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -59,49 +46,3 @@ pub fn resolveIdentity(comptime crypto_engine: Crypto.Engine) type {
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const expect = std.testing.expect;
|
const expect = std.testing.expect;
|
||||||
const memeql = std.mem.eql;
|
|
||||||
|
|
||||||
const testPattern: u8 = 0b10101010;
|
|
||||||
const pubkey_size = Crypto.Ed25519.public_key_length;
|
|
||||||
const privkey_size = Crypto.Ed25519.secret_key_length;
|
|
||||||
|
|
||||||
// Fills out with alternating 0s and 1s
|
|
||||||
fn fillPattern(out: []u8) void {
|
|
||||||
for(out) |*byte| {
|
|
||||||
byte.* = testPattern;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generateFakeKeys(destination: *Crypto.Ed25519.KeyPair, rng: Crypto.Random.Implementation) Crypto.CryptoError!void {
|
|
||||||
_ = rng;
|
|
||||||
fillPattern(&destination.public_key.bytes);
|
|
||||||
fillPattern(&destination.secret_key.bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "Basic identity generation" {
|
|
||||||
|
|
||||||
const fake_rng: Crypto.Random.Implementation = .{
|
|
||||||
.generate = fillPattern,
|
|
||||||
};
|
|
||||||
const fake_ed25519: Crypto.Ed25519.Implementation = .{
|
|
||||||
.generateKeys = generateFakeKeys,
|
|
||||||
.sign = undefined,
|
|
||||||
.verify = undefined,
|
|
||||||
};
|
|
||||||
const crypto_engine = comptime Crypto.resolveEngine(.{
|
|
||||||
.random = fake_rng,
|
|
||||||
.ed25519 = fake_ed25519,
|
|
||||||
});
|
|
||||||
|
|
||||||
const Identity = resolveIdentity(crypto_engine);
|
|
||||||
var new_id: Identity = undefined;
|
|
||||||
try new_id.generate();
|
|
||||||
|
|
||||||
const expected_secret_key = [_]u8{testPattern} ** new_id.keys.secret_key.bytes.len;
|
|
||||||
// const expected_signature_key = [_]u8{testPattern} ** new_id.signatureKeys.secret_key.len;
|
|
||||||
try expect(memeql(u8, &new_id.keys.secret_key.bytes, &expected_secret_key));
|
|
||||||
// try expect(memeql(u8, &new_id.signatureKeys.secret_key, &expected_signature_key));
|
|
||||||
|
|
||||||
// try expect(memeql(u8, new_id.hash, testPattern));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue