Refactored Ed25519 to use the stdlib's KeyPair type for better readability, separate generate() and new() identity functions, new update_hash() function for identity and compilation errors fixes
This commit is contained in:
parent
3209ae87a1
commit
69bad53a03
3 changed files with 46 additions and 26 deletions
|
|
@ -2,9 +2,13 @@
|
||||||
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 KeyPair = Ed25519.KeyPair;
|
||||||
|
|
||||||
pub const secret_key_length: comptime_int = Ed25519.SecretKey.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 public_key_length: comptime_int = Ed25519.PublicKey.encoded_length;
|
||||||
pub const signature_length : comptime_int = Ed25519.Signature.encoded_length;
|
pub const signature_length : comptime_int = Ed25519.Signature.encoded_length;
|
||||||
|
|
@ -12,20 +16,18 @@ pub const seed_length : comptime_int = Ed25519.Signature.encoded_length;
|
||||||
|
|
||||||
pub const Implementation = struct {
|
pub const Implementation = struct {
|
||||||
|
|
||||||
generateKeys: *const fn (pubkey_buffer: ?*[public_key_length]u8, privkey_buffer: *[secret_key_length]u8, rng: rngProvider) CryptoError!void,
|
generateKeys: *const fn (destination: *KeyPair, 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_length]u8, data: []const u8, signature_out: *const [signature_length]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_length]u8, signature: *const [signature_length]u8, data: []const u8) CryptoError!void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub fn generateKeys(pubkey_buffer: ?*[public_key_length]u8, privkey_buffer: *[secret_key_length]u8, rng: rngProvider) !void {
|
pub fn generateKeys (destination: *KeyPair, rng: rngProvider) !void {
|
||||||
|
|
||||||
var seed_buffer: [Ed25519.KeyPair.seed_length]u8 = undefined;
|
var seed_buffer: [KeyPair.seed_length]u8 = undefined;
|
||||||
|
defer secureZero(@TypeOf(seed_buffer), seed_buffer);
|
||||||
rng.generate(&seed_buffer);
|
rng.generate(&seed_buffer);
|
||||||
const keypair: Ed25519.KeyPair = Ed25519.KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
destination.* = KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
||||||
|
|
||||||
if (pubkey_buffer != null) @memcpy(pubkey_buffer.?[0..public_key_length], &keypair.public_key.bytes);
|
|
||||||
@memcpy(privkey_buffer[0..secret_key_length], &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_length]u8, data: []const u8, signature_out: *const [signature_length]u8) !void {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ const Ed25519 = @import("std").crypto.sign.Ed25519;
|
||||||
// Random number generation
|
// Random number generation
|
||||||
const rngProvider = @import("random.zig").Implementation;
|
const rngProvider = @import("random.zig").Implementation;
|
||||||
|
|
||||||
|
// Keypair type
|
||||||
|
pub const KeyPair = X25519.KeyPair;
|
||||||
|
|
||||||
pub const secret_key_length: comptime_int = X25519.secret_length;
|
pub const secret_key_length: comptime_int = X25519.secret_length;
|
||||||
pub const public_key_length: comptime_int = X25519.public_length;
|
pub const public_key_length: comptime_int = X25519.public_length;
|
||||||
pub const seed_length: comptime_int = X25519.seed_length;
|
pub const seed_length: comptime_int = X25519.seed_length;
|
||||||
|
|
@ -13,9 +16,9 @@ pub const seed_length: comptime_int = X25519.seed_length;
|
||||||
pub const Implementation = struct {
|
pub const Implementation = struct {
|
||||||
|
|
||||||
generateKeys: *const fn (pubkey_buffer: ?*[public_key_length]u8, privkey_buffer: *[secret_key_length]u8, rng: rngProvider) CryptoError!void,
|
generateKeys: *const fn (pubkey_buffer: ?*[public_key_length]u8, privkey_buffer: *[secret_key_length]u8, rng: rngProvider) CryptoError!void,
|
||||||
fromEd25519: *const fn (ed25519_keypair: *Ed25519.Keypair, x25519_keypair: *X25519.KeyPair, rng: rngProvider) CryptoError!void,
|
fromEd25519: *const fn (ed25519_keypair: *Ed25519.KeyPair, x25519_keypair: *KeyPair) CryptoError!void,
|
||||||
// TODO
|
// TODO
|
||||||
// maybe switch to a Keypair system based on the stdlib implementation
|
// Switch to a Keypair system based on the stdlib implementation
|
||||||
// generateKeys: *const fn (keypair: *X25519.KeyPair, rng: rngProvider) CryptoError!void,
|
// generateKeys: *const fn (keypair: *X25519.KeyPair, rng: rngProvider) CryptoError!void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -25,12 +28,12 @@ fn generateKeys (pubkey_buffer: ?*[public_key_length]u8, privkey_buffer: *[secre
|
||||||
rng.generate(&seed_buffer);
|
rng.generate(&seed_buffer);
|
||||||
const keypair: X25519.KeyPair = X25519.KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
const keypair: X25519.KeyPair = X25519.KeyPair.generateDeterministic(seed_buffer) catch return CryptoError.FailedKeyGeneration;
|
||||||
|
|
||||||
if (pubkey_buffer != null) @memcpy(pubkey_buffer.?[0..public_key_length], &keypair.public_key.bytes);
|
if (pubkey_buffer != null) @memcpy(pubkey_buffer.?[0..public_key_length], &keypair.public_key);
|
||||||
@memcpy(privkey_buffer[0..secret_key_length], &keypair.secret_key.bytes);
|
@memcpy(privkey_buffer[0..secret_key_length], &keypair.secret_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fromEd25519 (ed25519_keypair: *Ed25519.Keypair, x25519_keypair: *X25519.KeyPair) CryptoError!void {
|
fn fromEd25519 (ed25519_keypair: *Ed25519.KeyPair, x25519_keypair: *KeyPair) CryptoError!void {
|
||||||
x25519_keypair.* = X25519.KeyPair.fromEd25519(ed25519_keypair);
|
x25519_keypair.* = X25519.KeyPair.fromEd25519(ed25519_keypair.*) catch return CryptoError.InvalidKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const defaultImplementation: Implementation = .{
|
pub const defaultImplementation: Implementation = .{
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,31 @@ pub fn resolveIdentity(comptime crypto_engine: Crypto.Engine) type {
|
||||||
|
|
||||||
//////// Fields
|
//////// Fields
|
||||||
//
|
//
|
||||||
privKey: [Crypto.Ed25519.secret_key_length]u8,
|
keys: Crypto.Ed25519.KeyPair,
|
||||||
signatureKey: [Crypto.X25519.secret_key_size]u8,
|
signatureKeys: Crypto.X25519.KeyPair,
|
||||||
hash: []const u8,
|
hash: [Crypto.Sha256.hash_len]u8,
|
||||||
|
|
||||||
//////// Functions
|
//////// Functions
|
||||||
//
|
//
|
||||||
pub fn generate() !Self {
|
pub fn new() !Self {
|
||||||
const result: Self = undefined;
|
const result: Self = undefined;
|
||||||
crypto_engine.ed25519.generateKeys(null, &result.signatureKey, crypto_engine.random);
|
crypto_engine.ed25519.generateKeys(result.keys, crypto_engine.random);
|
||||||
// TODO privKey and signature
|
crypto_engine.x25519.fromEd25519(result.keys, result.signatureKeys, crypto_engine.random);
|
||||||
|
result.update_hash();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate(self: *Self) !void {
|
||||||
|
crypto_engine.ed25519.generateKeys(self.keys, crypto_engine.random);
|
||||||
|
crypto_engine.x25519.fromEd25519(self.keys, self.signatureKeys, crypto_engine.random);
|
||||||
|
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, self.hash);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,10 +72,10 @@ fn fillPattern(out: []u8) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generateFakeKeys(pubkey_buffer: *[pubkey_size]u8, privkey_buffer: *[privkey_size]u8, rng: Crypto.Random.Implementation) Crypto.CryptoError!void {
|
pub fn generateFakeKeys(destination: *Crypto.Ed25519.KeyPair, rng: Crypto.Random.Implementation) Crypto.CryptoError!void {
|
||||||
_ = rng;
|
_ = rng;
|
||||||
fillPattern(pubkey_buffer);
|
fillPattern(&destination.public_key.bytes);
|
||||||
fillPattern(privkey_buffer);
|
fillPattern(&destination.secret_key.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Basic identity generation" {
|
test "Basic identity generation" {
|
||||||
|
|
@ -72,6 +85,8 @@ test "Basic identity generation" {
|
||||||
};
|
};
|
||||||
const fake_ed25519: Crypto.Ed25519.Implementation = .{
|
const fake_ed25519: Crypto.Ed25519.Implementation = .{
|
||||||
.generateKeys = generateFakeKeys,
|
.generateKeys = generateFakeKeys,
|
||||||
|
.sign = undefined,
|
||||||
|
.verify = undefined,
|
||||||
};
|
};
|
||||||
const crypto_engine = Crypto.resolveEngine(.{
|
const crypto_engine = Crypto.resolveEngine(.{
|
||||||
.random = fake_rng,
|
.random = fake_rng,
|
||||||
|
|
@ -79,8 +94,8 @@ test "Basic identity generation" {
|
||||||
});
|
});
|
||||||
|
|
||||||
const Identity = resolveIdentity(crypto_engine);
|
const Identity = resolveIdentity(crypto_engine);
|
||||||
const new_id: Identity = try Identity.generate();
|
const new_id: Identity = undefined;
|
||||||
|
try new_id.generate();
|
||||||
|
|
||||||
try expect(memeql(u8, new_id.privKey, testPattern));
|
try expect(memeql(u8, new_id.privKey, testPattern));
|
||||||
try expect(memeql(u8, new_id.signatureKey, testPattern));
|
try expect(memeql(u8, new_id.signatureKey, testPattern));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue