summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libuecc/ecc.h13
-rw-r--r--src/ec25519.c19
2 files changed, 32 insertions, 0 deletions
diff --git a/include/libuecc/ecc.h b/include/libuecc/ecc.h
index 982f7c9..5d75150 100644
--- a/include/libuecc/ecc.h
+++ b/include/libuecc/ecc.h
@@ -87,6 +87,13 @@ void ecc_25519_store_packed(ecc_int256_t *out, const ecc_25519_work_t *in);
int ecc_25519_is_identity(const ecc_25519_work_t *in);
/**
+ * Negates a point of the Elliptic Curve
+ *
+ * The same pointer may be given for input and output
+ */
+void ecc_25519_negate(ecc_25519_work_t *out, const ecc_25519_work_t *in);
+
+/**
* Doubles a point of the Elliptic Curve
*
* ecc_25519_double(out, in) is equivalent to ecc_25519_add(out, in, in), but faster.
@@ -102,6 +109,12 @@ void ecc_25519_double(ecc_25519_work_t *out, const ecc_25519_work_t *in);
*/
void ecc_25519_add(ecc_25519_work_t *out, const ecc_25519_work_t *in1, const ecc_25519_work_t *in2);
+/**
+ * Subtracts two points of the Elliptic Curve
+ *
+ * The same pointers may be given for input and output.
+ */
+void ecc_25519_sub(ecc_25519_work_t *out, const ecc_25519_work_t *in1, const ecc_25519_work_t *in2);
/**
* Does a scalar multiplication of a point of the Elliptic Curve with an integer of a given bit length
diff --git a/src/ec25519.c b/src/ec25519.c
index a9d519c..d673aee 100644
--- a/src/ec25519.c
+++ b/src/ec25519.c
@@ -498,6 +498,18 @@ int ecc_25519_is_identity(const ecc_25519_work_t *in) {
return (check_zero(in->X)&check_zero(Y_Z));
}
+void ecc_25519_negate(ecc_25519_work_t *out, const ecc_25519_work_t *in) {
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ out->Y[i] = in->Y[i];
+ out->Z[i] = in->Z[i];
+ }
+
+ sub(out->X, zero, in->X);
+ sub(out->T, zero, in->T);
+}
+
void ecc_25519_double(ecc_25519_work_t *out, const ecc_25519_work_t *in) {
unsigned int A[32], B[32], C[32], D[32], E[32], F[32], G[32], H[32], t0[32], t1[32], t2[32], t3[32];
@@ -542,6 +554,13 @@ void ecc_25519_add(ecc_25519_work_t *out, const ecc_25519_work_t *in1, const ecc
mult(out->Z, F, G);
}
+void ecc_25519_sub(ecc_25519_work_t *out, const ecc_25519_work_t *in1, const ecc_25519_work_t *in2) {
+ ecc_25519_work_t in2_neg;
+
+ ecc_25519_negate(&in2_neg, in2);
+ ecc_25519_add(out, in1, &in2_neg);
+}
+
void ecc_25519_scalarmult_bits(ecc_25519_work_t *out, const ecc_int256_t *n, const ecc_25519_work_t *base, unsigned bits) {
ecc_25519_work_t Q2, Q2p;
ecc_25519_work_t cur = ecc_25519_work_identity;