mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-07 22:34:28 +00:00
crypto.sign.ed25519: include a context string in blind key signatures (#12316)
The next revision of the specification is going to include a context string in the way blinded scalars are computed. See: https://github.com/cfrg/draft-irtf-cfrg-signature-key-blinding/issues/30#issuecomment-1180516152 https://github.com/cfrg/draft-irtf-cfrg-signature-key-blinding/pull/37
This commit is contained in:
parent
447a4cc115
commit
fa321a07cd
1 changed files with 18 additions and 9 deletions
|
|
@ -229,15 +229,14 @@ pub const Ed25519 = struct {
|
||||||
blind_secret_key: BlindSecretKey,
|
blind_secret_key: BlindSecretKey,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Blind an existing key pair with a blinding seed.
|
/// Blind an existing key pair with a blinding seed and a context.
|
||||||
pub fn blind(key_pair: Ed25519.KeyPair, blind_seed: [blind_seed_length]u8) !BlindKeyPair {
|
pub fn blind(key_pair: Ed25519.KeyPair, blind_seed: [blind_seed_length]u8, ctx: []const u8) !BlindKeyPair {
|
||||||
var h: [Sha512.digest_length]u8 = undefined;
|
var h: [Sha512.digest_length]u8 = undefined;
|
||||||
Sha512.hash(key_pair.secret_key[0..32], &h, .{});
|
Sha512.hash(key_pair.secret_key[0..32], &h, .{});
|
||||||
Curve.scalar.clamp(h[0..32]);
|
Curve.scalar.clamp(h[0..32]);
|
||||||
const scalar = Curve.scalar.reduce(h[0..32].*);
|
const scalar = Curve.scalar.reduce(h[0..32].*);
|
||||||
|
|
||||||
var blind_h: [Sha512.digest_length]u8 = undefined;
|
const blind_h = blindCtx(blind_seed, ctx);
|
||||||
Sha512.hash(blind_seed[0..], &blind_h, .{});
|
|
||||||
const blind_factor = Curve.scalar.reduce(blind_h[0..32].*);
|
const blind_factor = Curve.scalar.reduce(blind_h[0..32].*);
|
||||||
|
|
||||||
const blind_scalar = Curve.scalar.mul(scalar, blind_factor);
|
const blind_scalar = Curve.scalar.mul(scalar, blind_factor);
|
||||||
|
|
@ -259,9 +258,8 @@ pub const Ed25519 = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recover a public key from a blind version of it.
|
/// Recover a public key from a blind version of it.
|
||||||
pub fn unblindPublicKey(blind_public_key: [public_length]u8, blind_seed: [blind_seed_length]u8) ![public_length]u8 {
|
pub fn unblindPublicKey(blind_public_key: [public_length]u8, blind_seed: [blind_seed_length]u8, ctx: []const u8) ![public_length]u8 {
|
||||||
var blind_h: [Sha512.digest_length]u8 = undefined;
|
const blind_h = blindCtx(blind_seed, ctx);
|
||||||
Sha512.hash(&blind_seed, &blind_h, .{});
|
|
||||||
const inv_blind_factor = Scalar.fromBytes(blind_h[0..32].*).invert().toBytes();
|
const inv_blind_factor = Scalar.fromBytes(blind_h[0..32].*).invert().toBytes();
|
||||||
const public_key = try (try Curve.fromBytes(blind_public_key)).mul(inv_blind_factor);
|
const public_key = try (try Curve.fromBytes(blind_public_key)).mul(inv_blind_factor);
|
||||||
return public_key.toBytes();
|
return public_key.toBytes();
|
||||||
|
|
@ -297,6 +295,17 @@ pub const Ed25519 = struct {
|
||||||
mem.copy(u8, sig[32..], s[0..]);
|
mem.copy(u8, sig[32..], s[0..]);
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute a blind context from a blinding seed and a context.
|
||||||
|
fn blindCtx(blind_seed: [blind_seed_length]u8, ctx: []const u8) [Sha512.digest_length]u8 {
|
||||||
|
var blind_h: [Sha512.digest_length]u8 = undefined;
|
||||||
|
var hx = Sha512.init(.{});
|
||||||
|
hx.update(&blind_seed);
|
||||||
|
hx.update(&[1]u8{0});
|
||||||
|
hx.update(ctx);
|
||||||
|
hx.final(&blind_h);
|
||||||
|
return blind_h;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -458,7 +467,7 @@ test "ed25519 with blind keys" {
|
||||||
crypto.random.bytes(&blind);
|
crypto.random.bytes(&blind);
|
||||||
|
|
||||||
// Blind the key pair
|
// Blind the key pair
|
||||||
const blind_kp = try BlindKeySignatures.blind(kp, blind);
|
const blind_kp = try BlindKeySignatures.blind(kp, blind, "ctx");
|
||||||
|
|
||||||
// Sign a message and check that it can be verified with the blind public key
|
// Sign a message and check that it can be verified with the blind public key
|
||||||
const msg = "test";
|
const msg = "test";
|
||||||
|
|
@ -466,6 +475,6 @@ test "ed25519 with blind keys" {
|
||||||
try Ed25519.verify(sig, msg, blind_kp.blind_public_key);
|
try Ed25519.verify(sig, msg, blind_kp.blind_public_key);
|
||||||
|
|
||||||
// Unblind the public key
|
// Unblind the public key
|
||||||
const pk = try BlindKeySignatures.unblindPublicKey(blind_kp.blind_public_key, blind);
|
const pk = try BlindKeySignatures.unblindPublicKey(blind_kp.blind_public_key, blind, "ctx");
|
||||||
try std.testing.expectEqualSlices(u8, &pk, &kp.public_key);
|
try std.testing.expectEqualSlices(u8, &pk, &kp.public_key);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue