WRT the selected answer here: Can curve25519 keys be used with ed25519 keys?
Is there any c# implementation of this or equivalent?
Thanks.
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<byte> montgomery, ArraySegment<byte> 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] & 0x80);// copy sign
}
public static void MontgomeryToEdwards(ArraySegment<byte> edwards, ArraySegment<byte> 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] & 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:
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] &= 0x7F
before passing it to MontgomeryCurve25519.KeyExchange
. I will change this property with the next update of the library.
crypto_box_beforenm
.