Upload files to "v1"
This commit is contained in:
136
v1/curve25519.d
Normal file
136
v1/curve25519.d
Normal file
@@ -0,0 +1,136 @@
|
||||
module angel.utils.cryptography.curve25519;
|
||||
|
||||
import angel.utils.cryptography.fieldelem;
|
||||
import angel.utils.cryptography.utils;
|
||||
|
||||
public enum ubyte[32] publicBasePoint = cast(immutable (ubyte[32]) ) x"0900000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
@safe nothrow @nogc:
|
||||
|
||||
///
|
||||
///
|
||||
/// Params:
|
||||
/// secret = Your secret key, the 'exponent'.
|
||||
/// p = Receivers public key. Default base point = 9.
|
||||
///
|
||||
/// Returns: p^secret.
|
||||
///
|
||||
/// Examples:
|
||||
///
|
||||
/// ubyte[32] publicKey = curve25519_scalarmult(secretKey);
|
||||
///
|
||||
/// ubyte[32] sharedKey = curve25519_scalarmult(mySecretKey, herPublicKey);
|
||||
///
|
||||
ubyte[32] curve25519_scalarmult(
|
||||
in ubyte[] secret,
|
||||
in ubyte[] p = cast(const ubyte[32]) publicBasePoint) @safe nothrow @nogc
|
||||
in {
|
||||
assert(secret.length == 32, "Secret key must be 32 bytes long.");
|
||||
assert(p.length == 32, "Public key must be 32 bytes long.");
|
||||
} body {
|
||||
ubyte[32] sec = secret;
|
||||
scope(exit) {
|
||||
wipe(sec);
|
||||
}
|
||||
|
||||
ubyte[32] pub = p;
|
||||
|
||||
return curve25519_scalarmult(sec, pub);
|
||||
}
|
||||
|
||||
///
|
||||
///
|
||||
/// Params:
|
||||
/// secret = Your secret key, the 'exponent'.
|
||||
/// p = Receivers public key. Default base point = 9.
|
||||
///
|
||||
/// Returns: p^secret.
|
||||
///
|
||||
/// Examples:
|
||||
///
|
||||
/// ubyte[32] publicKey = curve25519_scalarmult(secretKey);
|
||||
///
|
||||
/// ubyte[32] sharedKey = curve25519_scalarmult(mySecretKey, herPublicKey);
|
||||
///
|
||||
ubyte[32] curve25519_scalarmult(in ref ubyte[32] secret, in ref ubyte[32] p = publicBasePoint) @safe nothrow @nogc
|
||||
{
|
||||
ubyte[32] e = secret;
|
||||
scope(exit) {
|
||||
wipe(e);
|
||||
}
|
||||
clamp(e);
|
||||
|
||||
fe x1, x2, x3, z2, z3, tmp0, tmp1;
|
||||
scope(exit) {
|
||||
wipe(x1);
|
||||
wipe(x2);
|
||||
wipe(x3);
|
||||
wipe(z2);
|
||||
wipe(z3);
|
||||
wipe(tmp0);
|
||||
wipe(tmp1);
|
||||
}
|
||||
|
||||
x1 = fe.fromBytes(p);
|
||||
x2 = fe.one;
|
||||
z2 = fe.zero;
|
||||
x3 = x1;
|
||||
z3 = fe.one;
|
||||
|
||||
uint swap = 0, b;
|
||||
for (int pos = 254; pos >= 0;--pos) {
|
||||
b = e[pos / 8] >> (pos & 7);
|
||||
b &= 1;
|
||||
swap ^= b;
|
||||
fe_cswap(x2,x3,swap);
|
||||
fe_cswap(z2,z3,swap);
|
||||
swap = b;
|
||||
|
||||
tmp0 = x3 - z3;
|
||||
|
||||
tmp1 = x2 - z2;
|
||||
x2 += z2;
|
||||
z2 = x3 + z3;
|
||||
|
||||
z3 = tmp0 * x2;
|
||||
|
||||
z2 *= tmp1;
|
||||
tmp0 = tmp1.sq;
|
||||
tmp1 = x2.sq;
|
||||
x3 = z2 + z3;
|
||||
|
||||
z2 = z3 - z2;
|
||||
x2 = tmp0 * tmp1;
|
||||
|
||||
tmp1 -= tmp0;
|
||||
|
||||
z2 = z2.sq;
|
||||
|
||||
z3 = fe_mul121666(tmp1);
|
||||
|
||||
x3 = x3.sq;
|
||||
|
||||
tmp0 += z3;
|
||||
z3 = x1 * z2;
|
||||
|
||||
z2 = tmp0 * tmp1;
|
||||
}
|
||||
fe_cswap(x2,x3,swap);
|
||||
fe_cswap(z2,z3,swap);
|
||||
|
||||
x2 *= z2.inverse;
|
||||
return x2.toBytes;
|
||||
}
|
||||
|
||||
/// Transforms 32 random bytes into a valid secret key.
|
||||
///
|
||||
/// Params:
|
||||
/// sk = 32 byte secret key.
|
||||
package void clamp(ubyte[] sk) pure
|
||||
in {
|
||||
assert(sk.length == 32);
|
||||
} body {
|
||||
sk[0] &= 248;
|
||||
sk[31] &= 63;
|
||||
sk[31] |= 64;
|
||||
}
|
||||
Reference in New Issue
Block a user