C# implementation of curve25519 to ed25519 conversions WRT the selected answer here:
Can curve25519 keys be used with ed25519 keys?

Is there any c# implementation of this or equivalent?

Thanks.
In a Ref10 based implementation, the conversion should look something like this:



public static void EdwardsToMontgomeryX(out FieldElement montgomeryX, ref FieldElement edwardsY, ref FieldElement edwardsZ)
{
    // montgomeryX = (edwardsZ + edwardsY) / (edwardsZ - edwardsY)
    FieldElement tempX, tempZ;
    FieldOperations.fe_add(out tempX, ref edwardsZ, ref edwardsY);
    FieldOperations.fe_sub(out tempZ, ref edwardsZ, ref edwardsY);
    FieldOperations.fe_invert(out tempZ, ref tempZ);
    FieldOperations.fe_mul(out montgomeryX, ref tempX, ref tempZ);
}

public static void MontgomeryXToEdwards(out FieldElement edwardsY, ref FieldElement montgomeryX, ref FieldElement montgomeryZ)
{
    // edwardsY = (montgomeryX - montgomeryZ) / (montgomeryX + montgomeryZ)
    FieldElement tempY, tempZ;
    FieldOperations.fe_sub(out tempY, ref montgomeryX, ref montgomeryZ);
    FieldOperations.fe_add(out tempZ, ref montgomeryX, ref montgomeryZ);
    FieldOperations.fe_invert(out tempZ, ref tempZ);
    FieldOperations.fe_mul(out edwardsY, ref tempY, ref tempZ);
}

public static void EdwardsToMontgomery(ArraySegment&lt;byte&gt; montgomery, ArraySegment&lt;byte&gt; edwards)
{
    FieldElement edwardsY, edwardsZ, montgomeryX;
    FieldOperations.fe_frombytes(out edwardsY, edwards.Array, edwards.Offset);
    FieldOperations.fe_1(out edwardsZ);
    EdwardsToMontgomeryX(out montgomeryX, ref edwardsY, ref edwardsZ);
    FieldOperations.fe_tobytes(montgomery.Array, montgomery.Offset, ref montgomeryX);
    montgomery.Array[montgomery.Offset + 31] |= (byte)(edwards.Array[edwards.Offset + 31] &amp; 0x80);// copy sign
}

public static void MontgomeryToEdwards(ArraySegment&lt;byte&gt; edwards, ArraySegment&lt;byte&gt; montgomery)
{
    FieldElement montgomeryX, montgomeryZ, edwardsY;
    FieldOperations.fe_frombytes(out montgomeryX, montgomery.Array, montgomery.Offset);
    FieldOperations.fe_1(out montgomeryZ);
    MontgomeryXToEdwards(out edwardsY, ref montgomeryX, ref montgomeryZ);
    FieldOperations.fe_tobytes(edwards.Array, edwards.Offset, ref edwardsY);
    edwards.Array[edwards.Offset + 31] |= (byte)(montgomery.Array[montgomery.Offset + 31] &amp; 0x80);// copy sign
}


You should be able to use these together with my implementation at github.com/CodesInChaos/Chaos.NaCl. If all you need is crypto_box_beforenm except with a Ed25519 format key, you can simply use the existing Ed25519.KeyExchange method.

A few warnings:


I'm planning some breaking API changes
I'm not happy yet with the test coverage yet, so be careful
The Montogomery form Curve25519 functions don't ignore the last bit of the public key.

This means that you must manually mask out that bit via publicKey[31] &amp;= 0x7F before passing it to MontgomeryCurve25519.KeyExchange. I will change this property with the next update of the library.
The key exchange functions hash their output, matching crypto_box_beforenm.