summaryrefslogtreecommitdiff
path: root/libs/libaxolotl/src/curve25519/ed25519/additions
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 07:56:33 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 09:09:08 +0300
commit193f645f65ad4ffdec3186e4176b23af10861199 (patch)
treee1b16b48ac74c5f03f99a98798e849f6dd9752cc /libs/libaxolotl/src/curve25519/ed25519/additions
parent36c32a13878d3bd94e88bd9c764f1eadb05ea1ed (diff)
libs:
libaxolotl: updated libaxolotl (libsignal-c) from (https://github.com/WhisperSystems/libsignal-protocol-c)
Diffstat (limited to 'libs/libaxolotl/src/curve25519/ed25519/additions')
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h69
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c64
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h35
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c111
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c14
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c17
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c19
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c50
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c30
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c16
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c69
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c70
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c15
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c21
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c140
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c21
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c21
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h12
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c45
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c8
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c21
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c25
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c6
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c100
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c62
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/utility.c29
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/utility.h11
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c85
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c62
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c91
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h18
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c82
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h16
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c3
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h2
35 files changed, 1374 insertions, 86 deletions
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h b/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h
new file mode 100644
index 0000000000..da4a1cd07b
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/crypto_additions.h
@@ -0,0 +1,69 @@
+
+#ifndef __CRYPTO_ADDITIONS__
+#define __CRYPTO_ADDITIONS__
+
+#include "crypto_uint32.h"
+#include "fe.h"
+#include "ge.h"
+
+#define MAX_MSG_LEN 256
+
+void sc_neg(unsigned char *b, const unsigned char *a);
+void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b);
+
+int fe_isequal(const fe f, const fe g);
+void fe_mont_rhs(fe v2, const fe u);
+void fe_montx_to_edy(fe y, const fe u);
+void fe_sqrt(fe b, const fe a);
+
+int ge_is_small_order(const ge_p3 *p);
+int ge_isneutral(const ge_p3* q);
+void ge_neg(ge_p3* r, const ge_p3 *p);
+void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit);
+void ge_p3_to_montx(fe u, const ge_p3 *p);
+void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A);
+void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p);
+
+void elligator(fe u, const fe r);
+void hash_to_point(ge_p3* p, const unsigned char* msg, const unsigned long in_len);
+void calculate_Bv(ge_p3* Bv,
+ unsigned char* buf,
+ const unsigned char* A,
+ const unsigned char* msg, const unsigned long msg_len);
+void calculate_Bv_and_V(ge_p3* Bv,
+ unsigned char* V,
+ unsigned char* buf,
+ const unsigned char* a,
+ const unsigned char* A,
+ const unsigned char* msg, const unsigned long msg_len);
+
+int crypto_sign_modified(
+ unsigned char *sm,
+ const unsigned char *m,unsigned long long mlen,
+ const unsigned char *sk, /* Curve/Ed25519 private key */
+ const unsigned char *pk, /* Ed25519 public key */
+ const unsigned char *random /* 64 bytes random to hash into nonce */
+ );
+
+int crypto_sign_open_modified(
+ unsigned char *m,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk
+ );
+
+int crypto_vsign_modified(
+ unsigned char *sm,
+ const unsigned char *M,unsigned long Mlen,
+ const unsigned char *a,
+ const unsigned char *A,
+ const unsigned char *random,
+ const ge_p3 *Bu,
+ const unsigned char *U);
+
+int crypto_vsign_open_modified(
+ unsigned char *m,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk, const ge_p3* Bu);
+
+
+#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c
index 2a0aa54d4f..7a49b18aaa 100644
--- a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.c
@@ -3,36 +3,7 @@
#include "ge.h"
#include "curve_sigs.h"
#include "crypto_sign.h"
-
-void curve25519_keygen(unsigned char* curve25519_pubkey_out,
- const unsigned char* curve25519_privkey_in)
-{
- ge_p3 ed; /* Ed25519 pubkey point */
- fe ed_y, ed_y_plus_one, one_minus_ed_y, inv_one_minus_ed_y;
- fe mont_x;
-
- /* Perform a fixed-base multiplication of the Edwards base point,
- (which is efficient due to precalculated tables), then convert
- to the Curve25519 montgomery-format public key. In particular,
- convert Curve25519's "montgomery" x-coordinate into an Ed25519
- "edwards" y-coordinate:
-
- mont_x = (ed_y + 1) / (1 - ed_y)
-
- with projective coordinates:
-
- mont_x = (ed_y + ed_z) / (ed_z - ed_y)
-
- NOTE: ed_y=1 is converted to mont_x=0 since fe_invert is mod-exp
- */
-
- ge_scalarmult_base(&ed, curve25519_privkey_in);
- fe_add(ed_y_plus_one, ed.Y, ed.Z);
- fe_sub(one_minus_ed_y, ed.Z, ed.Y);
- fe_invert(inv_one_minus_ed_y, one_minus_ed_y);
- fe_mul(mont_x, ed_y_plus_one, inv_one_minus_ed_y);
- fe_tobytes(curve25519_pubkey_out, mont_x);
-}
+#include "crypto_additions.h"
int curve25519_sign(unsigned char* signature_out,
const unsigned char* curve25519_privkey,
@@ -71,18 +42,16 @@ int curve25519_verify(const unsigned char* signature,
const unsigned char* curve25519_pubkey,
const unsigned char* msg, const unsigned long msg_len)
{
- fe mont_x, mont_x_minus_one, mont_x_plus_one, inv_mont_x_plus_one;
- fe one;
- fe ed_y;
+ fe u;
+ fe y;
unsigned char ed_pubkey[32];
- unsigned long long some_retval;
- unsigned char *verifybuf = NULL; /* working buffer */
+ unsigned char *verifybuf = NULL; /* working buffer */
unsigned char *verifybuf2 = NULL; /* working buffer #2 */
int result;
if ((verifybuf = malloc(msg_len + 64)) == 0) {
- result = -1;
- goto err;
+ result = -1;
+ goto err;
}
if ((verifybuf2 = malloc(msg_len + 64)) == 0) {
@@ -91,22 +60,18 @@ int curve25519_verify(const unsigned char* signature,
}
/* Convert the Curve25519 public key into an Ed25519 public key. In
- particular, convert Curve25519's "montgomery" x-coordinate into an
+ particular, convert Curve25519's "montgomery" x-coordinate (u) into an
Ed25519 "edwards" y-coordinate:
- ed_y = (mont_x - 1) / (mont_x + 1)
+ y = (u - 1) / (u + 1)
- NOTE: mont_x=-1 is converted to ed_y=0 since fe_invert is mod-exp
+ NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp
Then move the sign bit into the pubkey from the signature.
*/
- fe_frombytes(mont_x, curve25519_pubkey);
- fe_1(one);
- fe_sub(mont_x_minus_one, mont_x, one);
- fe_add(mont_x_plus_one, mont_x, one);
- fe_invert(inv_mont_x_plus_one, mont_x_plus_one);
- fe_mul(ed_y, mont_x_minus_one, inv_mont_x_plus_one);
- fe_tobytes(ed_pubkey, ed_y);
+ fe_frombytes(u, curve25519_pubkey);
+ fe_montx_to_edy(y, u);
+ fe_tobytes(ed_pubkey, y);
/* Copy the sign bit, and remove it from signature */
ed_pubkey[31] &= 0x7F; /* bit should be zero already, but just in case */
@@ -120,9 +85,8 @@ int curve25519_verify(const unsigned char* signature,
/* The below call has a strange API: */
/* verifybuf = R || S || message */
/* verifybuf2 = internal to next call gets a copy of verifybuf, S gets
- replaced with pubkey for hashing, then the whole thing gets zeroized
- (if bad sig), or contains a copy of msg (good sig) */
- result = crypto_sign_open(verifybuf2, &some_retval, verifybuf, 64 + msg_len, ed_pubkey);
+ replaced with pubkey for hashing */
+ result = crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey);
err:
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h
index b3dbad0155..a2d819aef0 100644
--- a/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/curve_sigs.h
@@ -2,47 +2,16 @@
#ifndef __CURVE_SIGS_H__
#define __CURVE_SIGS_H__
-void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */
- const unsigned char* curve25519_privkey_in); /* 32 bytes */
-
/* returns 0 on success */
int curve25519_sign(unsigned char* signature_out, /* 64 bytes */
const unsigned char* curve25519_privkey, /* 32 bytes */
- const unsigned char* msg, const unsigned long msg_len,
+ const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */
const unsigned char* random); /* 64 bytes */
/* returns 0 on success */
int curve25519_verify(const unsigned char* signature, /* 64 bytes */
const unsigned char* curve25519_pubkey, /* 32 bytes */
- const unsigned char* msg, const unsigned long msg_len);
-
-/* helper function - modified version of crypto_sign() to use
- explicit private key. In particular:
-
- sk : private key
- pk : public key
- msg : message
- prefix : 0xFE || [0xFF]*31
- random : 64 bytes random
- q : main subgroup order
-
- The prefix is chosen to distinguish the two SHA512 uses below, since
- prefix is an invalid encoding for R (it would encode a "field element"
- of 2^255 - 2). 0xFF*32 is set aside for use in ECDH protocols, which
- is why the first byte here ix 0xFE.
+ const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */
- sig_nonce = SHA512(prefix || sk || msg || random) % q
- R = g^sig_nonce
- M = SHA512(R || pk || m)
- S = sig_nonce + (m * sk)
- signature = (R || S)
- */
-int crypto_sign_modified(
- unsigned char *sm,
- const unsigned char *m,unsigned long long mlen,
- const unsigned char *sk, /* Curve/Ed25519 private key */
- const unsigned char *pk, /* Ed25519 public key */
- const unsigned char *random /* 64 bytes random to hash into nonce */
- );
#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c b/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c
new file mode 100644
index 0000000000..8a8131ff2f
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/elligator.c
@@ -0,0 +1,111 @@
+#include <string.h>
+#include "fe.h"
+#include "ge.h"
+#include "crypto_uint32.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_additions.h"
+
+unsigned int legendre_is_nonsquare(fe in)
+{
+ fe temp;
+ fe_pow22523(temp, in); /* temp = in^((q-5)/8) */
+ fe_sq(temp, temp); /* in^((q-5)/4) */
+ fe_sq(temp, temp); /* in^((q-5)/2) */
+ fe_mul(temp, temp, in); /* in^((q-3)/2) */
+ fe_mul(temp, temp, in); /* in^((q-1)/2) */
+
+ /* temp is now the Legendre symbol:
+ * 1 = square
+ * 0 = input is zero
+ * -1 = nonsquare
+ */
+ unsigned char bytes[32];
+ fe_tobytes(bytes, temp);
+ return 1 & bytes[31];
+}
+
+void elligator(fe u, const fe r)
+{
+ /* r = input
+ * x = -A/(1+2r^2) # 2 is nonsquare
+ * e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol
+ * if e == 1 (square) or e == 0 (because x == 0 and 2r^2 + 1 == 0)
+ * u = x
+ * if e == -1 (nonsquare)
+ * u = -x - A
+ */
+ fe A, one, twor2, twor2plus1, twor2plus1inv;
+ fe x, e, Atemp, uneg;
+ unsigned int nonsquare;
+
+ fe_1(one);
+ fe_0(A);
+ A[0] = 486662; /* A = 486662 */
+
+ fe_sq2(twor2, r); /* 2r^2 */
+ fe_add(twor2plus1, twor2, one); /* 1+2r^2 */
+ fe_invert(twor2plus1inv, twor2plus1); /* 1/(1+2r^2) */
+ fe_mul(x, twor2plus1inv, A); /* A/(1+2r^2) */
+ fe_neg(x, x); /* x = -A/(1+2r^2) */
+
+ fe_mont_rhs(e, x); /* e = x^3 + Ax^2 + x */
+ nonsquare = legendre_is_nonsquare(e);
+
+ fe_0(Atemp);
+ fe_cmov(Atemp, A, nonsquare); /* 0, or A if nonsquare */
+ fe_add(u, x, Atemp); /* x, or x+A if nonsquare */
+ fe_neg(uneg, u); /* -x, or -x-A if nonsquare */
+ fe_cmov(u, uneg, nonsquare); /* x, or -x-A if nonsquare */
+}
+
+void hash_to_point(ge_p3* p, const unsigned char* in, const unsigned long in_len)
+{
+ unsigned char hash[64];
+ fe h, u;
+ unsigned char sign_bit;
+ ge_p3 p3;
+
+ crypto_hash_sha512(hash, in, in_len);
+
+ /* take the high bit as Edwards sign bit */
+ sign_bit = (hash[31] & 0x80) >> 7;
+ hash[31] &= 0x7F;
+ fe_frombytes(h, hash);
+ elligator(u, h);
+
+ ge_montx_to_p3(&p3, u, sign_bit);
+ ge_scalarmult_cofactor(p, &p3);
+}
+
+
+void calculate_Bv(ge_p3* Bv,
+ unsigned char* buf,
+ const unsigned char* A,
+ const unsigned char* msg, const unsigned long msg_len)
+{
+ int count;
+
+ /* Calculate SHA512(label(2) || A || msg) */
+ buf[0] = 0xFD;
+ for (count = 1; count < 32; count++)
+ buf[count] = 0xFF;
+ memmove(buf+32, A, 32);
+ memmove(buf+64, msg, msg_len);
+
+ hash_to_point(Bv, buf, 64 + msg_len);
+}
+
+
+void calculate_Bv_and_V(ge_p3* Bv,
+ unsigned char* V,
+ unsigned char* buf,
+ const unsigned char* a,
+ const unsigned char* A,
+ const unsigned char* msg, const unsigned long msg_len)
+{
+ ge_p3 p3;
+
+ calculate_Bv(Bv, buf, A, msg, msg_len);
+ ge_scalarmult(&p3, a, Bv);
+ ge_p3_tobytes(V, &p3);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c
new file mode 100644
index 0000000000..67c5d33c96
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_isequal.c
@@ -0,0 +1,14 @@
+#include "fe.h"
+#include "crypto_verify_32.h"
+
+/*
+return 1 if f == g
+return 0 if f != g
+*/
+
+int fe_isequal(const fe f, const fe g)
+{
+ fe h;
+ fe_sub(h, f, g);
+ return 1 ^ (1 & (fe_isnonzero(h) >> 8));
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c
new file mode 100644
index 0000000000..bc8393620c
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_mont_rhs.c
@@ -0,0 +1,17 @@
+#include "fe.h"
+
+void fe_mont_rhs(fe v2, fe u) {
+ fe A, one;
+ fe u2, Au, inner;
+
+ fe_1(one);
+ fe_0(A);
+ A[0] = 486662; /* A = 486662 */
+
+ fe_sq(u2, u); /* u^2 */
+ fe_mul(Au, A, u); /* Au */
+ fe_add(inner, u2, Au); /* u^2 + Au */
+ fe_add(inner, inner, one); /* u^2 + Au + 1 */
+ fe_mul(v2, u, inner); /* u(u^2 + Au + 1) */
+}
+
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c
new file mode 100644
index 0000000000..b0f8c63276
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_montx_to_edy.c
@@ -0,0 +1,19 @@
+
+#include "fe.h"
+#include "crypto_additions.h"
+
+void fe_montx_to_edy(fe y, const fe u)
+{
+ /*
+ y = (u - 1) / (u + 1)
+
+ NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp
+ */
+ fe one, um1, up1;
+
+ fe_1(one);
+ fe_sub(um1, u, one);
+ fe_add(up1, u, one);
+ fe_invert(up1, up1);
+ fe_mul(y, um1, up1);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c
new file mode 100644
index 0000000000..906d38b93e
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/fe_sqrt.c
@@ -0,0 +1,50 @@
+#include <assert.h>
+#include "fe.h"
+#include "crypto_additions.h"
+
+/* sqrt(-1) */
+static unsigned char i_bytes[32] = {
+ 0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4,
+ 0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f,
+ 0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b,
+ 0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b
+};
+
+/* Preconditions: a is square or zero */
+
+void fe_sqrt(fe out, const fe a)
+{
+ fe exp, b, b2, bi, i;
+
+ fe_frombytes(i, i_bytes);
+ fe_pow22523(exp, a); /* b = a^(q-5)/8 */
+
+ /* PRECONDITION: legendre symbol == 1 (square) or 0 (a == zero) */
+#ifndef NDEBUG
+ fe legendre, zero, one;
+
+ fe_sq(legendre, exp); /* in^((q-5)/4) */
+ fe_sq(legendre, legendre); /* in^((q-5)/2) */
+ fe_mul(legendre, legendre, a); /* in^((q-3)/2) */
+ fe_mul(legendre, legendre, a); /* in^((q-1)/2) */
+
+ fe_0(zero);
+ fe_1(one);
+ assert(fe_isequal(legendre, zero) || fe_isequal(legendre, one));
+#endif
+
+ fe_mul(b, a, exp); /* b = a * a^(q-5)/8 */
+ fe_sq(b2, b); /* b^2 = a * a^(q-1)/4 */
+
+ /* note b^4 == a^2, so b^2 == a or -a
+ * if b^2 != a, multiply it by sqrt(-1) */
+ fe_mul(bi, b, i);
+ fe_cmov(b, bi, 1 ^ fe_isequal(b2, a));
+ fe_copy(out, b);
+
+ /* PRECONDITION: out^2 == a */
+#ifndef NDEBUG
+ fe_sq(b2, out);
+ assert(fe_isequal(a, b2));
+#endif
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c
new file mode 100644
index 0000000000..845941be2a
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_is_small_order.c
@@ -0,0 +1,30 @@
+#include "crypto_additions.h"
+#include "ge.h"
+#include "utility.h"
+#include "stdio.h"
+
+/*
+return 1 if f == g
+return 0 if f != g
+*/
+
+int ge_is_small_order(const ge_p3 *p)
+{
+ ge_p1p1 p1p1;
+ ge_p2 p2;
+ fe zero;
+
+ ge_p3_dbl(&p1p1, p);
+ ge_p1p1_to_p2(&p2, &p1p1);
+
+ ge_p2_dbl(&p1p1, &p2);
+ ge_p1p1_to_p2(&p2, &p1p1);
+
+ ge_p2_dbl(&p1p1, &p2);
+ ge_p1p1_to_p2(&p2, &p1p1);
+
+ fe_0(zero);
+
+ /* Check if 8*p == neutral element == (0, 1) */
+ return (fe_isequal(p2.X, zero) & fe_isequal(p2.Y, p2.Z));
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c
new file mode 100644
index 0000000000..d40e443682
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_isneutral.c
@@ -0,0 +1,16 @@
+#include "crypto_additions.h"
+#include "ge.h"
+
+/*
+return 1 if p is the neutral point
+return 0 otherwise
+*/
+
+int ge_isneutral(const ge_p3 *p)
+{
+ fe zero;
+ fe_0(zero);
+
+ /* Check if p == neutral element == (0, 1) */
+ return (fe_isequal(p->X, zero) & fe_isequal(p->Y, p->Z));
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c
new file mode 100644
index 0000000000..d123d03580
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p2.c
@@ -0,0 +1,69 @@
+#include "fe.h"
+#include "ge.h"
+#include "assert.h"
+#include "crypto_additions.h"
+#include "utility.h"
+
+/* sqrt(-(A+2)) */
+static unsigned char A_bytes[32] = {
+ 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc,
+ 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5,
+ 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2,
+ 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f
+};
+
+void ge_montx_to_p2(ge_p2* p, const fe u, const unsigned char ed_sign_bit)
+{
+ fe x, y, A, v, v2, iv, nx;
+
+ fe_frombytes(A, A_bytes);
+
+ /* given u, recover edwards y */
+ /* given u, recover v */
+ /* given u and v, recover edwards x */
+
+ fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */
+
+ fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */
+ fe_sqrt(v, v2); /* v = sqrt(v^2) */
+
+ fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */
+ fe_invert(iv, v); /* 1/v */
+ fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */
+
+ fe_neg(nx, x); /* negate x to match sign bit */
+ fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit);
+
+ fe_copy(p->X, x);
+ fe_copy(p->Y, y);
+ fe_1(p->Z);
+
+ /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */
+ /* -x^2 + y^2 = 1 + dx^2y^2 */
+#ifndef NDEBUG
+ {
+ fe one, d, x2, y2, x2y2, dx2y2;
+
+ unsigned char dbytes[32] = {
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
+ };
+
+ fe_frombytes(d, dbytes);
+ fe_1(one);
+ fe_sq(x2, p->X); /* x^2 */
+ fe_sq(y2, p->Y); /* y^2 */
+
+ fe_mul(dx2y2, x2, y2); /* x^2y^2 */
+ fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */
+ fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */
+
+ fe_neg(x2y2, x2); /* -x^2 */
+ fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */
+
+ assert(fe_isequal(x2y2, dx2y2));
+ }
+#endif
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c
new file mode 100644
index 0000000000..7a716c5a72
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_montx_to_p3.c
@@ -0,0 +1,70 @@
+#include "fe.h"
+#include "ge.h"
+#include "assert.h"
+#include "crypto_additions.h"
+#include "utility.h"
+
+/* sqrt(-(A+2)) */
+static unsigned char A_bytes[32] = {
+ 0x06, 0x7e, 0x45, 0xff, 0xaa, 0x04, 0x6e, 0xcc,
+ 0x82, 0x1a, 0x7d, 0x4b, 0xd1, 0xd3, 0xa1, 0xc5,
+ 0x7e, 0x4f, 0xfc, 0x03, 0xdc, 0x08, 0x7b, 0xd2,
+ 0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f
+};
+
+void ge_montx_to_p3(ge_p3* p, const fe u, const unsigned char ed_sign_bit)
+{
+ fe x, y, A, v, v2, iv, nx;
+
+ fe_frombytes(A, A_bytes);
+
+ /* given u, recover edwards y */
+ /* given u, recover v */
+ /* given u and v, recover edwards x */
+
+ fe_montx_to_edy(y, u); /* y = (u - 1) / (u + 1) */
+
+ fe_mont_rhs(v2, u); /* v^2 = u(u^2 + Au + 1) */
+ fe_sqrt(v, v2); /* v = sqrt(v^2) */
+
+ fe_mul(x, u, A); /* x = u * sqrt(-(A+2)) */
+ fe_invert(iv, v); /* 1/v */
+ fe_mul(x, x, iv); /* x = (u/v) * sqrt(-(A+2)) */
+
+ fe_neg(nx, x); /* negate x to match sign bit */
+ fe_cmov(x, nx, fe_isnegative(x) ^ ed_sign_bit);
+
+ fe_copy(p->X, x);
+ fe_copy(p->Y, y);
+ fe_1(p->Z);
+ fe_mul(p->T, p->X, p->Y);
+
+ /* POSTCONDITION: check that p->X and p->Y satisfy the Ed curve equation */
+ /* -x^2 + y^2 = 1 + dx^2y^2 */
+#ifndef NDEBUG
+ {
+ fe one, d, x2, y2, x2y2, dx2y2;
+
+ unsigned char dbytes[32] = {
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
+ };
+
+ fe_frombytes(d, dbytes);
+ fe_1(one);
+ fe_sq(x2, p->X); /* x^2 */
+ fe_sq(y2, p->Y); /* y^2 */
+
+ fe_mul(dx2y2, x2, y2); /* x^2y^2 */
+ fe_mul(dx2y2, dx2y2, d); /* dx^2y^2 */
+ fe_add(dx2y2, dx2y2, one); /* dx^2y^2 + 1 */
+
+ fe_neg(x2y2, x2); /* -x^2 */
+ fe_add(x2y2, x2y2, y2); /* -x^2 + y^2 */
+
+ assert(fe_isequal(x2y2, dx2y2));
+ }
+#endif
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c
new file mode 100644
index 0000000000..d679713fe0
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_neg.c
@@ -0,0 +1,15 @@
+#include "crypto_additions.h"
+#include "ge.h"
+
+/*
+return r = -p
+*/
+
+
+void ge_neg(ge_p3* r, const ge_p3 *p)
+{
+ fe_neg(r->X, p->X);
+ fe_copy(r->Y, p->Y);
+ fe_copy(r->Z, p->Z);
+ fe_neg(r->T, p->T);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c
new file mode 100644
index 0000000000..b539b2f17f
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_p3_to_montx.c
@@ -0,0 +1,21 @@
+#include "fe.h"
+#include "crypto_additions.h"
+
+void ge_p3_to_montx(fe u, const ge_p3 *ed)
+{
+ /*
+ u = (y + 1) / (1 - y)
+ or
+ u = (y + z) / (z - y)
+
+ NOTE: y=1 is converted to u=0 since fe_invert is mod-exp
+ */
+
+ fe y_plus_one, one_minus_y, inv_one_minus_y;
+
+ fe_add(y_plus_one, ed->Y, ed->Z);
+ fe_sub(one_minus_y, ed->Z, ed->Y);
+ fe_invert(inv_one_minus_y, one_minus_y);
+ fe_mul(u, y_plus_one, inv_one_minus_y);
+}
+
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c
new file mode 100644
index 0000000000..e4f741b8d8
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult.c
@@ -0,0 +1,140 @@
+#include "crypto_uint32.h"
+#include "ge.h"
+#include "crypto_additions.h"
+
+static unsigned char equal(signed char b,signed char c)
+{
+ unsigned char ub = b;
+ unsigned char uc = c;
+ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
+ crypto_uint32 y = x; /* 0: yes; 1..255: no */
+ y -= 1; /* 4294967295: yes; 0..254: no */
+ y >>= 31; /* 1: yes; 0: no */
+ return y;
+}
+
+static unsigned char negative(signed char b)
+{
+ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
+ x >>= 63; /* 1: yes; 0: no */
+ return x;
+}
+
+static void cmov(ge_cached *t,const ge_cached *u,unsigned char b)
+{
+ fe_cmov(t->YplusX,u->YplusX,b);
+ fe_cmov(t->YminusX,u->YminusX,b);
+ fe_cmov(t->Z,u->Z,b);
+ fe_cmov(t->T2d,u->T2d,b);
+}
+
+static void select(ge_cached *t,const ge_cached *pre, signed char b)
+{
+ ge_cached minust;
+ unsigned char bnegative = negative(b);
+ unsigned char babs = b - (((-bnegative) & b) << 1);
+
+ fe_1(t->YplusX);
+ fe_1(t->YminusX);
+ fe_1(t->Z);
+ fe_0(t->T2d);
+
+ cmov(t,pre+0,equal(babs,1));
+ cmov(t,pre+1,equal(babs,2));
+ cmov(t,pre+2,equal(babs,3));
+ cmov(t,pre+3,equal(babs,4));
+ cmov(t,pre+4,equal(babs,5));
+ cmov(t,pre+5,equal(babs,6));
+ cmov(t,pre+6,equal(babs,7));
+ cmov(t,pre+7,equal(babs,8));
+ fe_copy(minust.YplusX,t->YminusX);
+ fe_copy(minust.YminusX,t->YplusX);
+ fe_copy(minust.Z,t->Z);
+ fe_neg(minust.T2d,t->T2d);
+ cmov(t,&minust,bnegative);
+}
+
+/*
+h = a * B
+where a = a[0]+256*a[1]+...+256^31 a[31]
+B is the Ed25519 base point (x,4/5) with x positive.
+
+Preconditions:
+ a[31] <= 127
+*/
+
+void ge_scalarmult(ge_p3 *h, const unsigned char *a, const ge_p3 *A)
+{
+ signed char e[64];
+ signed char carry;
+ ge_p1p1 r;
+ ge_p2 s;
+ ge_p3 t0, t1, t2;
+ ge_cached t, pre[8];
+ int i;
+
+ for (i = 0;i < 32;++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 15;
+ e[2 * i + 1] = (a[i] >> 4) & 15;
+ }
+ /* each e[i] is between 0 and 15 */
+ /* e[63] is between 0 and 7 */
+
+ carry = 0;
+ for (i = 0;i < 63;++i) {
+ e[i] += carry;
+ carry = e[i] + 8;
+ carry >>= 4;
+ e[i] -= carry << 4;
+ }
+ e[63] += carry;
+ /* each e[i] is between -8 and 8 */
+
+ // Precomputation:
+ ge_p3_to_cached(pre+0, A); // A
+
+ ge_p3_dbl(&r, A);
+ ge_p1p1_to_p3(&t0, &r);
+ ge_p3_to_cached(pre+1, &t0); // 2A
+
+ ge_add(&r, A, pre+1);
+ ge_p1p1_to_p3(&t1, &r);
+ ge_p3_to_cached(pre+2, &t1); // 3A
+
+ ge_p3_dbl(&r, &t0);
+ ge_p1p1_to_p3(&t0, &r);
+ ge_p3_to_cached(pre+3, &t0); // 4A
+
+ ge_add(&r, A, pre+3);
+ ge_p1p1_to_p3(&t2, &r);
+ ge_p3_to_cached(pre+4, &t2); // 5A
+
+ ge_p3_dbl(&r, &t1);
+ ge_p1p1_to_p3(&t1, &r);
+ ge_p3_to_cached(pre+5, &t1); // 6A
+
+ ge_add(&r, A, pre+5);
+ ge_p1p1_to_p3(&t1, &r);
+ ge_p3_to_cached(pre+6, &t1); // 7A
+
+ ge_p3_dbl(&r, &t0);
+ ge_p1p1_to_p3(&t0, &r);
+ ge_p3_to_cached(pre+7, &t0); // 8A
+
+ ge_p3_0(h);
+
+ for (i = 63;i > 0; i--) {
+ select(&t,pre,e[i]);
+ ge_add(&r, h, &t);
+ ge_p1p1_to_p2(&s,&r);
+
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);
+
+ }
+ select(&t,pre,e[0]);
+ ge_add(&r, h, &t);
+ ge_p1p1_to_p3(h,&r);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c
new file mode 100644
index 0000000000..6affbb05d5
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/ge_scalarmult_cofactor.c
@@ -0,0 +1,21 @@
+#include "crypto_additions.h"
+#include "ge.h"
+
+/*
+return 8 * p
+*/
+
+void ge_scalarmult_cofactor(ge_p3 *q, const ge_p3 *p)
+{
+ ge_p1p1 p1p1;
+ ge_p2 p2;
+
+ ge_p3_dbl(&p1p1, p);
+ ge_p1p1_to_p2(&p2, &p1p1);
+
+ ge_p2_dbl(&p1p1, &p2);
+ ge_p1p1_to_p2(&p2, &p1p1);
+
+ ge_p2_dbl(&p1p1, &p2);
+ ge_p1p1_to_p3(q, &p1p1);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c
new file mode 100644
index 0000000000..de7cdcd598
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.c
@@ -0,0 +1,21 @@
+#include "ge.h"
+#include "keygen.h"
+#include "crypto_additions.h"
+
+void curve25519_keygen(unsigned char* curve25519_pubkey_out,
+ const unsigned char* curve25519_privkey_in)
+{
+ /* Perform a fixed-base multiplication of the Edwards base point,
+ (which is efficient due to precalculated tables), then convert
+ to the Curve25519 montgomery-format public key.
+
+ NOTE: y=1 is converted to u=0 since fe_invert is mod-exp
+ */
+
+ ge_p3 ed; /* Ed25519 pubkey point */
+ fe u;
+
+ ge_scalarmult_base(&ed, curve25519_privkey_in);
+ ge_p3_to_montx(u, &ed);
+ fe_tobytes(curve25519_pubkey_out, u);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h
new file mode 100644
index 0000000000..e86e7c5582
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/keygen.h
@@ -0,0 +1,12 @@
+
+#ifndef __KEYGEN_H__
+#define __KEYGEN_H__
+
+/* Sets and clears bits to make a random 32 bytes into a private key */
+void sc_clamp(unsigned char* a);
+
+/* The private key should be 32 random bytes "clamped" by sc_clamp() */
+void curve25519_keygen(unsigned char* curve25519_pubkey_out, /* 32 bytes */
+ const unsigned char* curve25519_privkey_in); /* 32 bytes */
+
+#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c
new file mode 100644
index 0000000000..a156098191
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/open_modified.c
@@ -0,0 +1,45 @@
+#include <string.h>
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "ge.h"
+#include "sc.h"
+#include "crypto_additions.h"
+
+int crypto_sign_open_modified(
+ unsigned char *m,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk
+)
+{
+ unsigned char pkcopy[32];
+ unsigned char rcopy[32];
+ unsigned char scopy[32];
+ unsigned char h[64];
+ unsigned char rcheck[32];
+ ge_p3 A;
+ ge_p2 R;
+
+ if (smlen < 64) goto badsig;
+ if (sm[63] & 224) goto badsig; /* strict parsing of s */
+ if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
+
+ memmove(pkcopy,pk,32);
+ memmove(rcopy,sm,32);
+ memmove(scopy,sm + 32,32);
+
+ memmove(m,sm,smlen);
+ memmove(m + 32,pkcopy,32);
+ crypto_hash_sha512(h,m,smlen);
+ sc_reduce(h);
+
+ ge_double_scalarmult_vartime(&R,h,&A,scopy);
+ ge_tobytes(rcheck,&R);
+
+ if (crypto_verify_32(rcheck,rcopy) == 0) {
+ return 0;
+ }
+
+badsig:
+ return -1;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c
new file mode 100644
index 0000000000..7788be9071
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_clamp.c
@@ -0,0 +1,8 @@
+#include "crypto_additions.h"
+
+void sc_clamp(unsigned char* a)
+{
+ a[0] &= 248;
+ a[31] &= 127;
+ a[31] |= 64;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c
new file mode 100644
index 0000000000..443a5bb71e
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_cmov.c
@@ -0,0 +1,21 @@
+#include "crypto_additions.h"
+
+/*
+Replace (f,g) with (g,g) if b == 1;
+replace (f,g) with (f,g) if b == 0.
+
+Preconditions: b in {0,1}.
+*/
+
+void sc_cmov(unsigned char* f, const unsigned char* g, unsigned char b)
+{
+ int count=32;
+ unsigned char x[32];
+ for (count=0; count < 32; count++)
+ x[count] = f[count] ^ g[count];
+ b = -b;
+ for (count=0; count < 32; count++)
+ x[count] &= b;
+ for (count=0; count < 32; count++)
+ f[count] = f[count] ^ x[count];
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c
new file mode 100644
index 0000000000..ef407d405e
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sc_neg.c
@@ -0,0 +1,25 @@
+#include <string.h>
+#include "crypto_additions.h"
+#include "sc.h"
+
+/* l = order of base point = 2^252 + 27742317777372353535851937790883648493 */
+
+/*
+static unsigned char l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+ 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x10};
+*/
+
+static unsigned char lminus1[32] = {0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
+ 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
+
+/* b = -a (mod l) */
+void sc_neg(unsigned char *b, const unsigned char *a)
+{
+ unsigned char zero[32];
+ memset(zero, 0, 32);
+ sc_muladd(b, lminus1, a, zero); /* b = (-1)a + 0 (mod l) */
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c
index 61332e70e7..b2fb8c20d3 100644
--- a/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/sign_modified.c
@@ -4,6 +4,7 @@
#include "ge.h"
#include "sc.h"
#include "zeroize.h"
+#include "crypto_additions.h"
/* NEW: Compare to pristine crypto_sign()
Uses explicit private key for nonce derivation and as scalar,
@@ -36,6 +37,7 @@ int crypto_sign_modified(
memmove(sm + 32,pk,32);
sc_reduce(nonce);
+
ge_scalarmult_base(&R,nonce);
ge_p3_tobytes(sm,&R);
@@ -43,5 +45,9 @@ int crypto_sign_modified(
sc_reduce(hram);
sc_muladd(sm + 32,hram,sk,nonce); /* NEW: Use privkey directly */
+ /* Erase any traces of private scalar or
+ nonce left in the stack from sc_muladd */
+ zeroize_stack();
+ zeroize(nonce, 64);
return 0;
}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c
new file mode 100644
index 0000000000..412f8c4c9b
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c
@@ -0,0 +1,100 @@
+#include <string.h>
+#include "sc.h"
+#include "ge.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "crypto_additions.h"
+#include "crypto_sign.h"
+
+int crypto_usign_open_modified(
+ unsigned char *m,unsigned long long *mlen,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk, const ge_p3* Bu
+)
+{
+ ge_p3 U;
+ unsigned char h[64];
+ unsigned char s[64];
+ unsigned char strict[64];
+ ge_p3 A;
+ ge_p2 R;
+ unsigned char hcheck[64];
+ int count;
+
+ if (smlen < 96) goto badsig;
+ if (sm[63] & 224) goto badsig; /* strict parsing of h */
+ if (sm[95] & 224) goto badsig; /* strict parsing of s */
+
+ /* Load -A */
+ if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig;
+
+ /* Load -U, h, s */
+ ge_frombytes_negate_vartime(&U, sm);
+ memset(h, 0, 64);
+ memset(s, 0, 64);
+ memmove(h, sm + 32, 32);
+ memmove(s, sm + 64, 32);
+
+ /* Insist that s and h are reduced scalars (strict parsing) */
+ memcpy(strict, h, 64);
+ sc_reduce(strict);
+ if (memcmp(strict, h, 32) != 0)
+ goto badsig;
+ memcpy(strict, s, 64);
+ sc_reduce(strict);
+ if (memcmp(strict, s, 32) != 0)
+ goto badsig;
+
+ /* Reject U (actually -U) if small order */
+ if (ge_is_small_order(&U))
+ goto badsig;
+
+ // R = sB + h(-A)
+ ge_double_scalarmult_vartime(&R,h,&A,s);
+
+ // Ru = sBu + h(-U)
+ ge_p3 sBu, hU;
+
+ // sBu
+ ge_scalarmult(&sBu, s, Bu);
+
+ // h(-U)
+ ge_scalarmult(&hU, h, &U);
+
+ // Ru = sBu + h(-U)
+ ge_p1p1 Rp1p1;
+ ge_p3 Ru;
+ ge_cached hUcached;
+ ge_p3_to_cached(&hUcached, &hU);
+ ge_add(&Rp1p1, &sBu, &hUcached);
+ ge_p1p1_to_p3(&Ru, &Rp1p1);
+
+
+ // Check h == SHA512(label(4) || A || U || R || Ru || M)
+ m[0] = 0xFB;
+ for (count = 1; count < 32; count++)
+ m[count] = 0xFF;
+ memmove(m+32, pk, 32);
+ /* undo the negation for U */
+ fe_neg(U.X, U.X);
+ fe_neg(U.T, U.T);
+ ge_p3_tobytes(m+64, &U);
+ ge_tobytes(m+96, &R);
+ ge_p3_tobytes(m+128, &Ru);
+ memmove(m+160, sm+96, smlen - 96);
+
+ crypto_hash_sha512(hcheck, m, smlen + 64);
+ sc_reduce(hcheck);
+
+ if (crypto_verify_32(hcheck, h) == 0) {
+ memmove(m,m + 64,smlen - 64);
+ memset(m + smlen - 64,0,64);
+ *mlen = smlen - 64;
+ return 0;
+ }
+
+badsig:
+ *mlen = -1;
+ memset(m,0,smlen);
+ return -1;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c
new file mode 100644
index 0000000000..3bbd871b7a
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/usign_modified.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "ge.h"
+#include "sc.h"
+#include "zeroize.h"
+#include "crypto_additions.h"
+
+/* NEW: Compare to pristine crypto_sign()
+ Uses explicit private key for nonce derivation and as scalar,
+ instead of deriving both from a master key.
+*/
+int crypto_usign_modified(
+ unsigned char *sm,
+ const unsigned char *M,unsigned long Mlen,
+ const unsigned char *a,
+ const unsigned char *A,
+ const unsigned char *random,
+ const ge_p3 *Bu,
+ const unsigned char *U
+)
+{
+ unsigned char r[64];
+ unsigned char h[64];
+ ge_p3 R, Ru;
+ int count=0;
+
+ /* r = SHA512(label(3) || a || U || random(64)) */
+ sm[0] = 0xFC;
+ for (count = 1; count < 32; count++)
+ sm[count] = 0xFF;
+
+ memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */
+ memmove(sm + 64, U, 32);
+
+ memmove(sm + 96, random, 64); /* Add suffix of random data */
+ crypto_hash_sha512(r, sm, 160);
+
+ sc_reduce(r);
+ ge_scalarmult_base(&R, r);
+ ge_scalarmult(&Ru, r, Bu);
+
+ /* h = SHA512(label(4) || A || U || R || Ru || M) */
+ sm[0] = 0xFB;
+ memmove(sm + 32, A, 32);
+ memmove(sm + 64, U, 32);
+ ge_p3_tobytes(sm+96, &R);
+ ge_p3_tobytes(sm+128, &Ru);
+ memmove(sm + 160, M, Mlen);
+
+ crypto_hash_sha512(h, sm, Mlen + 160);
+ sc_reduce(h);
+
+ memmove(sm, h, 32); /* Write h */
+ sc_muladd(sm + 32, h, a, r); /* Write s */
+
+ /* Erase any traces of private scalar or
+ nonce left in the stack from sc_muladd. */
+ zeroize_stack();
+ zeroize(r, 64);
+ return 0;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c
new file mode 100644
index 0000000000..c59099a9e3
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "utility.h"
+
+void print_vector(const char* name, const unsigned char* v)
+{
+ int count;
+ printf("%s = \n", name);
+ for (count = 0; count < 32; count++)
+ printf("%02x ", v[count]);
+ printf("\n");
+}
+
+void print_bytes(const char* name, const unsigned char* v, int numbytes)
+{
+ int count;
+ printf("%s = \n", name);
+ for (count = 0; count < numbytes; count++)
+ printf("%02x ", v[count]);
+ printf("\n");
+}
+
+void print_fe(const char* name, const fe in)
+{
+ unsigned char bytes[32];
+ fe_tobytes(bytes, in);
+ print_vector(name, bytes);
+}
+
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h
new file mode 100644
index 0000000000..35348782df
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/utility.h
@@ -0,0 +1,11 @@
+
+#ifndef __UTILITY_H__
+#define __UTILITY_H__
+
+#include "fe.h"
+
+void print_vector(const char* name, const unsigned char* v);
+void print_bytes(const char* name, const unsigned char* v, int numbytes);
+void print_fe(const char* name, const fe in);
+
+#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
new file mode 100644
index 0000000000..3dfc7fba6f
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
@@ -0,0 +1,85 @@
+#include <string.h>
+#include "sc.h"
+#include "ge.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "crypto_additions.h"
+#include "crypto_sign.h"
+
+int crypto_vsign_open_modified(
+ unsigned char *m,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk, const ge_p3* Bv
+)
+{
+ ge_p3 Vneg, V, Aneg, A, c_V, c_A, h_Vneg, s_Bv;
+ unsigned char h[32];
+ unsigned char s[32];
+ ge_p2 R;
+ unsigned char hcheck[64];
+ unsigned char vrf_output[64];
+ int count;
+
+ if (smlen < 96) goto badsig;
+ if (sm[63] & 224) goto badsig; /* strict parsing of h */
+ if (sm[95] & 224) goto badsig; /* strict parsing of s */
+
+ /* Load -A */
+ if (ge_frombytes_negate_vartime(&Aneg,pk) != 0) goto badsig;
+
+ /* Load -V, h, s */
+ if (ge_frombytes_negate_vartime(&Vneg, sm) != 0) goto badsig;
+ memmove(h, sm + 32, 32);
+ memmove(s, sm + 64, 32);
+ if (h[31] & 224) goto badsig; /* strict parsing of h */
+ if (s[31] & 224) goto badsig; /* strict parsing of s */
+
+ ge_neg(&A, &Aneg);
+ ge_neg(&V, &Vneg);
+ ge_scalarmult_cofactor(&c_A, &A);
+ ge_scalarmult_cofactor(&c_V, &V);
+ if (ge_isneutral(&c_A) || ge_isneutral(&c_V) || ge_isneutral(Bv))
+ goto badsig;
+
+ // R = (s*B) + (h * -A))
+ ge_double_scalarmult_vartime(&R, h, &Aneg, s);
+
+ // s * Bv
+ ge_scalarmult(&s_Bv, s, Bv);
+
+ // h * -V
+ ge_scalarmult(&h_Vneg, h, &Vneg);
+
+ // Rv = (sc * Bv) + (hc * (-V))
+ ge_p1p1 Rp1p1;
+ ge_p3 Rv;
+ ge_cached h_Vnegcached;
+ ge_p3_to_cached(&h_Vnegcached, &h_Vneg);
+ ge_add(&Rp1p1, &s_Bv, &h_Vnegcached);
+ ge_p1p1_to_p3(&Rv, &Rp1p1);
+
+ // Check h == SHA512(label(4) || A || V || R || Rv || M)
+ m[0] = 0xFB; // label 4
+ for (count = 1; count < 32; count++)
+ m[count] = 0xFF;
+ memmove(m+32, pk, 32);
+ ge_p3_tobytes(m+64, &V);
+ ge_tobytes(m+96, &R);
+ ge_p3_tobytes(m+128, &Rv);
+ memmove(m+160, sm+96, smlen - 96);
+
+ crypto_hash_sha512(hcheck, m, smlen + 64);
+ sc_reduce(hcheck);
+
+ if (crypto_verify_32(hcheck, h) == 0) {
+ ge_p3_tobytes(m+32, &c_V);
+ m[0] = 0xFA; // label 5
+ crypto_hash_sha512(vrf_output, m, 64);
+ memmove(m, vrf_output, 32);
+ return 0;
+ }
+
+badsig:
+ memset(m, 0, 32);
+ return -1;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c
new file mode 100644
index 0000000000..518b851d63
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vsign_modified.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include "crypto_sign.h"
+#include "crypto_hash_sha512.h"
+#include "ge.h"
+#include "sc.h"
+#include "zeroize.h"
+#include "crypto_additions.h"
+
+/* NEW: Compare to pristine crypto_sign()
+ Uses explicit private key for nonce derivation and as scalar,
+ instead of deriving both from a master key.
+*/
+int crypto_vsign_modified(
+ unsigned char *sm,
+ const unsigned char *M,unsigned long Mlen,
+ const unsigned char *a,
+ const unsigned char *A,
+ const unsigned char *random,
+ const ge_p3 *Bv,
+ const unsigned char *V
+)
+{
+ unsigned char r[64];
+ unsigned char h[64];
+ ge_p3 R, Rv;
+ int count=0;
+
+ /* r = SHA512(label(3) || a || V || random(64)) */
+ sm[0] = 0xFC;
+ for (count = 1; count < 32; count++)
+ sm[count] = 0xFF;
+
+ memmove(sm + 32, a, 32); /* Use privkey directly for nonce derivation */
+ memmove(sm + 64, V, 32);
+
+ memmove(sm + 96, random, 64); /* Add suffix of random data */
+ crypto_hash_sha512(r, sm, 160);
+
+ sc_reduce(r);
+ ge_scalarmult_base(&R, r);
+ ge_scalarmult(&Rv, r, Bv);
+
+ /* h = SHA512(label(4) || A || V || R || Rv || M) */
+ sm[0] = 0xFB;
+ memmove(sm + 32, A, 32);
+ memmove(sm + 64, V, 32);
+ ge_p3_tobytes(sm+96, &R);
+ ge_p3_tobytes(sm+128, &Rv);
+ memmove(sm + 160, M, Mlen);
+
+ crypto_hash_sha512(h, sm, Mlen + 160);
+ sc_reduce(h);
+
+ memmove(sm, h, 32); /* Write h */
+ sc_muladd(sm + 32, h, a, r); /* Write s */
+
+ /* Erase any traces of private scalar or
+ nonce left in the stack from sc_muladd. */
+ zeroize_stack();
+ zeroize(r, 64);
+ return 0;
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c
new file mode 100644
index 0000000000..802a73563d
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.c
@@ -0,0 +1,91 @@
+#include <string.h>
+#include "ge.h"
+#include "crypto_additions.h"
+#include "zeroize.h"
+#include "vxeddsa.h"
+#include "crypto_verify_32.h"
+
+int vxed25519_sign(unsigned char* signature_out,
+ const unsigned char* curve25519_privkey,
+ const unsigned char* msg, const unsigned long msg_len,
+ const unsigned char* random)
+{
+ unsigned char a[32], aneg[32];
+ unsigned char A[32];
+ ge_p3 Bv, ed_pubkey_point;
+ unsigned char sigbuf[MAX_MSG_LEN + 160]; /* working buffer */
+ unsigned char sign_bit = 0;
+
+ if (msg_len > MAX_MSG_LEN) {
+ memset(signature_out, 0, 96);
+ return -1;
+ }
+ /* Convert the Curve25519 privkey to an Ed25519 public key */
+ ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey);
+ ge_p3_tobytes(A, &ed_pubkey_point);
+
+ /* Force Edwards sign bit to zero */
+ sign_bit = (A[31] & 0x80) >> 7;
+ memcpy(a, curve25519_privkey, 32);
+ sc_neg(aneg, a);
+ sc_cmov(a, aneg, sign_bit);
+ A[31] &= 0x7F;
+
+ calculate_Bv_and_V(&Bv, signature_out, sigbuf, a, A, msg, msg_len);
+
+ /* Perform an Ed25519 signature with explicit private key */
+ crypto_vsign_modified(sigbuf, msg, msg_len, a, A, random, &Bv, signature_out /*V*/);
+ memmove(signature_out+32, sigbuf, 64);
+
+ zeroize(a, 32);
+ zeroize(aneg, 32);
+ return 0;
+}
+
+int vxed25519_verify(unsigned char* vrf_out,
+ const unsigned char* signature,
+ const unsigned char* curve25519_pubkey,
+ const unsigned char* msg, const unsigned long msg_len)
+{
+ fe u;
+ fe y;
+ unsigned char ed_pubkey[32];
+ unsigned char strict[32];
+ unsigned char verifybuf[MAX_MSG_LEN + 160]; /* working buffer */
+ unsigned char verifybuf2[MAX_MSG_LEN + 160]; /* working buffer #2 ?? !!! */
+ ge_p3 Bv;
+
+ if (msg_len > MAX_MSG_LEN) {
+ return -1;
+ }
+
+ /* Convert the Curve25519 public key (u) into an Ed25519 public key.
+
+ y = (u - 1) / (u + 1)
+
+ NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp
+ */
+ fe_frombytes(u, curve25519_pubkey);
+ fe_tobytes(strict, u);
+ if (crypto_verify_32(strict, curve25519_pubkey) != 0)
+ return 0;
+ fe_montx_to_edy(y, u);
+ fe_tobytes(ed_pubkey, y);
+
+ calculate_Bv(&Bv, verifybuf, ed_pubkey, msg, msg_len);
+
+ memmove(verifybuf, signature, 96);
+ memmove(verifybuf+96, msg, msg_len);
+
+ /* Then perform a signature verification, return 0 on success */
+ /* The below call has a strange API: */
+ /* verifybuf = V || h || s || message */
+ /* verifybuf2 = used as buffer, gets the VRF output if success */
+ if (crypto_vsign_open_modified(verifybuf2, verifybuf, 96 + msg_len, ed_pubkey, &Bv) == 0) {
+ memmove(vrf_out, verifybuf2, 32);
+ return 0;
+ } else {
+ memset(vrf_out, 0, 32);
+ return -1;
+ }
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h
new file mode 100644
index 0000000000..4e48844170
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vxeddsa.h
@@ -0,0 +1,18 @@
+
+#ifndef __VXEDDSA_H__
+#define __VXEDDSA_H__
+
+/* returns 0 on success */
+int vxed25519_sign(unsigned char* signature_out, /* 96 bytes */
+ const unsigned char* curve25519_privkey, /* 32 bytes */
+ const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */
+ const unsigned char* random); /* 64 bytes */
+
+/* returns 0 on success */
+int vxed25519_verify(unsigned char* vrf_out, /* 32 bytes */
+ const unsigned char* signature, /* 96 bytes */
+ const unsigned char* curve25519_pubkey, /* 32 bytes */
+ const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */
+
+
+#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c
new file mode 100644
index 0000000000..ee2964a0d5
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.c
@@ -0,0 +1,82 @@
+#include <string.h>
+#include "ge.h"
+#include "crypto_additions.h"
+#include "zeroize.h"
+#include "xeddsa.h"
+#include "crypto_verify_32.h"
+
+int xed25519_sign(unsigned char* signature_out,
+ const unsigned char* curve25519_privkey,
+ const unsigned char* msg, const unsigned long msg_len,
+ const unsigned char* random)
+{
+ unsigned char a[32], aneg[32];
+ unsigned char A[32];
+ ge_p3 ed_pubkey_point;
+ unsigned char *sigbuf; /* working buffer */
+ unsigned char sign_bit = 0;
+
+ if ((sigbuf = malloc(msg_len + 128)) == 0) {
+ memset(signature_out, 0, 64);
+ return -1;
+ }
+
+ /* Convert the Curve25519 privkey to an Ed25519 public key */
+ ge_scalarmult_base(&ed_pubkey_point, curve25519_privkey);
+ ge_p3_tobytes(A, &ed_pubkey_point);
+
+ /* Force Edwards sign bit to zero */
+ sign_bit = (A[31] & 0x80) >> 7;
+ memcpy(a, curve25519_privkey, 32);
+ sc_neg(aneg, a);
+ sc_cmov(a, aneg, sign_bit);
+ A[31] &= 0x7F;
+
+ /* Perform an Ed25519 signature with explicit private key */
+ crypto_sign_modified(sigbuf, msg, msg_len, a, A, random);
+ memmove(signature_out, sigbuf, 64);
+
+ zeroize(a, 32);
+ zeroize(aneg, 32);
+ free(sigbuf);
+ return 0;
+}
+
+int xed25519_verify(const unsigned char* signature,
+ const unsigned char* curve25519_pubkey,
+ const unsigned char* msg, const unsigned long msg_len)
+{
+ fe u;
+ fe y;
+ unsigned char ed_pubkey[32];
+ unsigned char strict[32];
+ unsigned char verifybuf[MAX_MSG_LEN + 64]; /* working buffer */
+ unsigned char verifybuf2[MAX_MSG_LEN + 64]; /* working buffer #2 */
+
+ if (msg_len > MAX_MSG_LEN) {
+ return -1;
+ }
+
+ /* Convert the Curve25519 public key into an Ed25519 public key.
+
+ y = (u - 1) / (u + 1)
+
+ NOTE: u=-1 is converted to y=0 since fe_invert is mod-exp
+ */
+ fe_frombytes(u, curve25519_pubkey);
+ fe_tobytes(strict, u);
+ if (crypto_verify_32(strict, curve25519_pubkey) != 0)
+ return 0;
+ fe_montx_to_edy(y, u);
+ fe_tobytes(ed_pubkey, y);
+
+ memmove(verifybuf, signature, 64);
+ memmove(verifybuf+64, msg, msg_len);
+
+ /* Then perform a normal Ed25519 verification, return 0 on success */
+ /* The below call has a strange API: */
+ /* verifybuf = R || S || message */
+ /* verifybuf2 = internal to next call gets a copy of verifybuf, S gets
+ replaced with pubkey for hashing */
+ return crypto_sign_open_modified(verifybuf2, verifybuf, 64 + msg_len, ed_pubkey);
+}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h
new file mode 100644
index 0000000000..b86d7f0d9d
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/xeddsa.h
@@ -0,0 +1,16 @@
+
+#ifndef __XEDDSA_H__
+#define __XEDDSA_H__
+
+/* returns 0 on success */
+int xed25519_sign(unsigned char* signature_out, /* 64 bytes */
+ const unsigned char* curve25519_privkey, /* 32 bytes */
+ const unsigned char* msg, const unsigned long msg_len, /* <= 256 bytes */
+ const unsigned char* random); /* 64 bytes */
+
+/* returns 0 on success */
+int xed25519_verify(const unsigned char* signature, /* 64 bytes */
+ const unsigned char* curve25519_pubkey, /* 32 bytes */
+ const unsigned char* msg, const unsigned long msg_len); /* <= 256 bytes */
+
+#endif
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c
index 37c1f708bc..187e725eb5 100644
--- a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.c
@@ -3,7 +3,6 @@
void zeroize(unsigned char* b, size_t len)
{
size_t count = 0;
- unsigned long retval = 0;
volatile unsigned char *p = b;
for (count = 0; count < len; count++)
@@ -13,5 +12,5 @@ void zeroize(unsigned char* b, size_t len)
void zeroize_stack()
{
unsigned char m[ZEROIZE_STACK_SIZE];
- zeroize(m, sizeof m);
+ zeroize(m, ZEROIZE_STACK_SIZE);
}
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h
index 80fcffb768..0db68bb4c6 100644
--- a/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/zeroize.h
@@ -3,7 +3,7 @@
#include <stdlib.h>
-#define ZEROIZE_STACK_SIZE 2048
+#define ZEROIZE_STACK_SIZE 1024
void zeroize(unsigned char* b, size_t len);