authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-02-23 19:53:09+01:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-02-23 19:53:09+01:00
logee82d926a646a25a5986591ade1f30e77eed0a34
tree4706f66e7f8116985df342c2ac5226b6a5f71bd5
parent27ef6e9a9b21ff7ca4e349af4384a3a23a1e3cde
parente8ca9229c8aa6bd2d8abb1f91a8662eed2e68fd5

Merge pull request 'Expose the elligator map for Curve25519' (#31318) from jedisct1/zig:elligator-curve25519 into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31318

1 files changed, 22 insertions(+), 0 deletions(-)

lib/std/crypto/25519/curve25519.zig+22
......@@ -101,6 +101,11 @@ pub const Curve25519 = struct {
101101 return try ladder(p, s, 256);
102102 }
103103
104 /// Elligator2 map for Curve25519.
105 pub fn elligator2(r: Fe) Curve25519 {
106 return .{ .x = crypto.ecc.Edwards25519.elligator2(r).x };
107 }
108
104109 /// Compute the Curve25519 equivalent to an Edwards25519 point.
105110 ///
106111 /// Note that the function doesn't check that the input point is
......@@ -145,6 +150,23 @@ test "non-affine edwards25519 to curve25519 projection" {
145150 try std.testing.expectEqualSlices(u8, &xp.toBytes(), &expected);
146151}
147152
153test "elligator2" {
154 const Fe = Curve25519.Fe;
155
156 // RFC 9380 Appendix J.4.2 test vector (curve25519_XMD:SHA-512_ELL2_NU_)
157 // u = 0x608d892b641f0328523802a6603427c26e55e6f27e71a91a478148d45b5093cd
158 // Q.x = 0x51125222da5e763d97f3c10fcc92ea6860b9ccbbd2eb1285728f566721c1e65b
159 const u = Fe.fromBytes(.{
160 0xcd, 0x93, 0x50, 0x5b, 0xd4, 0x48, 0x81, 0x47, 0x1a, 0xa9, 0x71, 0x7e, 0xf2, 0xe6, 0x55, 0x6e,
161 0xc2, 0x27, 0x34, 0x60, 0xa6, 0x02, 0x38, 0x52, 0x28, 0x03, 0x1f, 0x64, 0x2b, 0x89, 0x8d, 0x60,
162 });
163 const p = Curve25519.elligator2(u);
164 try std.testing.expectEqual([32]u8{
165 0x5b, 0xe6, 0xc1, 0x21, 0x67, 0x56, 0x8f, 0x72, 0x85, 0x12, 0xeb, 0xd2, 0xbb, 0xcc, 0xb9, 0x60,
166 0x68, 0xea, 0x92, 0xcc, 0x0f, 0xc1, 0xf3, 0x97, 0x3d, 0x76, 0x5e, 0xda, 0x22, 0x52, 0x12, 0x51,
167 }, p.toBytes());
168}
169
148170test "small order check" {
149171 var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31;
150172 const small_order_ss: [7][32]u8 = .{