| ... | @@ -105,7 +105,8 @@ pub const Curve25519 = struct { | ... | @@ -105,7 +105,8 @@ pub const Curve25519 = struct { |
| 105 | pub fn fromEdwards25519(p: crypto.ecc.Edwards25519) IdentityElementError!Curve25519 { | 105 | pub fn fromEdwards25519(p: crypto.ecc.Edwards25519) IdentityElementError!Curve25519 { |
| 106 | try p.clearCofactor().rejectIdentity(); | 106 | try p.clearCofactor().rejectIdentity(); |
| 107 | const one = crypto.ecc.Edwards25519.Fe.one; | 107 | const one = crypto.ecc.Edwards25519.Fe.one; |
| 108 | const x = one.add(p.y).mul(one.sub(p.y).invert()); // xMont=(1+yEd)/(1-yEd) | 108 | const py = p.y.mul(p.z.invert()); |
| | 109 | const x = one.add(py).mul(one.sub(py).invert()); // xMont=(1+yEd)/(1-yEd) |
| 109 | return Curve25519{ .x = x }; | 110 | return Curve25519{ .x = x }; |
| 110 | } | 111 | } |
| 111 | }; | 112 | }; |
| ... | @@ -124,6 +125,18 @@ test "curve25519" { | ... | @@ -124,6 +125,18 @@ test "curve25519" { |
| 124 | try std.testing.expectError(error.NonCanonical, Curve25519.rejectNonCanonical(s)); | 125 | try std.testing.expectError(error.NonCanonical, Curve25519.rejectNonCanonical(s)); |
| 125 | } | 126 | } |
| 126 | | 127 | |
| | 128 | test "non-affine edwards25519 to curve25519 projection" { |
| | 129 | const skh = "90e7595fc89e52fdfddce9c6a43d74dbf6047025ee0462d2d172e8b6a2841d6e"; |
| | 130 | var sk: [32]u8 = undefined; |
| | 131 | _ = std.fmt.hexToBytes(&sk, skh) catch unreachable; |
| | 132 | var edp = try crypto.ecc.Edwards25519.basePoint.mul(sk); |
| | 133 | const xp = try Curve25519.fromEdwards25519(edp); |
| | 134 | const expected_hex = "cc4f2cdb695dd766f34118eb67b98652fed1d8bc49c330b119bbfa8a64989378"; |
| | 135 | var expected: [32]u8 = undefined; |
| | 136 | _ = std.fmt.hexToBytes(&expected, expected_hex) catch unreachable; |
| | 137 | try std.testing.expectEqualSlices(u8, &xp.toBytes(), &expected); |
| | 138 | } |
| | 139 | |
| 127 | test "curve25519 small order check" { | 140 | test "curve25519 small order check" { |
| 128 | var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31; | 141 | var s: [32]u8 = [_]u8{1} ++ [_]u8{0} ** 31; |
| 129 | const small_order_ss: [7][32]u8 = .{ | 142 | const small_order_ss: [7][32]u8 = .{ |