diff options
| author | Nagi5Yeq <nagi5yeq@github.com> | 2019-07-04 20:43:45 +0800 |
|---|---|---|
| committer | Nagi5Yeq <nagi5yeq@github.com> | 2019-07-04 20:43:45 +0800 |
| commit | ac411589296383ff0432118264b3a4bf24766ad4 (patch) | |
| tree | f3186cdf6c1b81432765fd68223d54f1134896f0 | |
init commit
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | defs.h | 14 | ||||
| -rw-r--r-- | fe448.c | 345 | ||||
| -rw-r--r-- | fe448.h | 62 | ||||
| -rw-r--r-- | sc448.c | 291 | ||||
| -rw-r--r-- | sc448.h | 57 |
7 files changed, 779 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6190b1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.py +.vscode/
\ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bbec377 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# fe448 + +A naive implementation of ed448, may have many bugs... + +**Not finished yet.** + +Mainly modified from [SUPERCOP](https://bench.cr.yp.to/supercop.html) ed25519 ref implementation.
\ No newline at end of file @@ -0,0 +1,14 @@ +#ifndef DEFS_H +#define DEFS_H + +#include <stdint.h> +#include <stdlib.h> + +typedef int8_t crypto_int8; +typedef uint8_t crypto_uint8; +typedef int16_t crypto_int16; +typedef uint16_t crypto_uint16; +typedef int32_t crypto_int32; +typedef uint32_t crypto_uint32; + +#endif /* DEFS_H */ @@ -0,0 +1,345 @@ +#define WINDOWSIZE 1 /* Should be 1,2, or 4 */ +#define WINDOWMASK ((1 << WINDOWSIZE) - 1) + +#include "fe448.h" + +/* 2**448-2**224-1 */ +static const crypto_uint32 m[57] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}; + +/* 256**114//m */ +static const crypto_uint32 mu[59] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + +static crypto_uint32 equal(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ +{ + crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */ + x -= 1; /* 4294967295: yes; 0..65534: no */ + x >>= 31; /* 1: yes; 0: no */ + return x; +} + +static crypto_uint32 lt(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ +{ + unsigned int x = a; + x -= (unsigned int)b; /* 0..65535: no; 4294901761..4294967295: yes */ + x >>= 31; /* 0: no; 1: yes */ + return x; +} + +static void reduce_add_sub(fe448 *r) +{ + crypto_uint32 t; + int i, rep; + + for (rep = 0; rep < 4; rep++) + { + t = r->v[56]; + r->v[56] = 0; + r->v[0] += t; + r->v[28] += t; + for (i = 0; i < 56; i++) + { + t = r->v[i] >> 8; + r->v[i + 1] += t; + r->v[i] &= 255; + } + } +} + +/* copied from sc448.c, a bit of slowly on 2**448-2**224-1 */ +static void barrett_reduce(fe448 *r, const crypto_uint32 x[114]) +{ + /* See HAC, Alg. 14.42 */ + int i, j; + crypto_uint32 q2[116]; + crypto_uint32 *q3 = q2 + 58; + crypto_uint32 r1[58]; + crypto_uint32 r2[58]; + crypto_uint32 carry; + crypto_uint32 pb = 0; + crypto_uint32 b; + + for (i = 0; i < 116; ++i) + q2[i] = 0; + for (i = 0; i < 58; ++i) + r2[i] = 0; + + for (i = 0; i < 59; i++) + for (j = 0; j < 58; j++) + if (i + j >= 56) + q2[i + j] += mu[i] * x[j + 56]; + carry = q2[56] >> 8; + q2[57] += carry; + carry = q2[57] >> 8; + q2[58] += carry; + + for (i = 0; i < 58; i++) + r1[i] = x[i]; + for (i = 0; i < 57; i++) + for (j = 0; j < 58; j++) + if (i + j < 58) + r2[i + j] += m[i] * q3[j]; + + for (i = 0; i < 57; i++) + { + carry = r2[i] >> 8; + r2[i + 1] += carry; + r2[i] &= 0xff; + } + + for (i = 0; i < 57; i++) + { + pb += r2[i]; + b = lt(r1[i], pb); + r->v[i] = r1[i] - pb + (b << 8); + pb = b; + } + + reduce_add_sub(r); + reduce_add_sub(r); + reduce_add_sub(r); + reduce_add_sub(r); +} + +/* reduction modulo 2**448-2**224-1 */ +void fe448_freeze(fe448 *r) +{ + int i; + crypto_uint32 m0; + crypto_uint32 m1; + crypto_uint32 b = 0, t; + m0 = equal(r->v[56], 0); + for (i = 55; i > 28; i--) + m0 &= equal(r->v[i], 255); + m1 = m0; + m0 &= equal(r->v[28], 255); + m1 &= equal(r->v[28], 254); + for (i = 27; i >= 0; i--) + m1 &= equal(r->v[i], 255); + + m0 |= m1; + m0 = -m0; + + for (i = 0; i < 57; i++) + { + t = r->v[i] - m[i] - b; + r->v[i] -= (m[i] + b) & 255 & m0; + b = (t >> 8) & 1; + } +} + +void fe448_unpack(fe448 *r, const unsigned char x[57]) +{ + int i; + for (i = 0; i < 56; i++) + r->v[i] = x[i]; + r->v[56] = 0; +} + +/* Assumes input x being reduced below 2^448 */ +void fe448_pack(unsigned char r[57], const fe448 *x) +{ + int i; + fe448 y = *x; + fe448_freeze(&y); + for (i = 0; i < 57; i++) + r[i] = y.v[i]; +} + +int fe448_iszero(const fe448 *x) +{ + int i; + int r; + fe448 t = *x; + fe448_freeze(&t); + r = equal(t.v[0], 0); + for (i = 1; i < 57; i++) + r &= equal(t.v[i], 0); + return r; +} + +int fe448_iseq_vartime(const fe448 *x, const fe448 *y) +{ + int i; + fe448 t1 = *x; + fe448 t2 = *y; + fe448_freeze(&t1); + fe448_freeze(&t2); + for (i = 0; i < 57; i++) + if (t1.v[i] != t2.v[i]) + return 0; + return 1; +} + +void fe448_cmov(fe448 *r, const fe448 *x, unsigned char b) +{ + int i; + crypto_uint32 mask = b; + mask = -mask; + for (i = 0; i < 57; i++) + r->v[i] ^= mask & (x->v[i] ^ r->v[i]); +} + +unsigned char fe448_getparity(const fe448 *x) +{ + fe448 t = *x; + fe448_freeze(&t); + return t.v[0] & 1; +} + +void fe448_setone(fe448 *r) +{ + int i; + r->v[0] = 1; + for (i = 1; i < 57; i++) + r->v[i] = 0; +} + +void fe448_setzero(fe448 *r) +{ + int i; + for (i = 0; i < 57; i++) + r->v[i] = 0; +} + +void fe448_neg(fe448 *r, const fe448 *x) +{ + fe448 t; + int i; + for (i = 0; i < 57; i++) + t.v[i] = x->v[i]; + fe448_setzero(r); + fe448_sub(r, r, &t); +} + +void fe448_add(fe448 *r, const fe448 *x, const fe448 *y) +{ + int i; + for (i = 0; i < 57; i++) + r->v[i] = x->v[i] + y->v[i]; + reduce_add_sub(r); +} + +void fe448_sub(fe448 *r, const fe448 *x, const fe448 *y) +{ + int i; + crypto_uint32 t[57]; + for (i = 0; i < 28; i++) /* add x with p previously so that r>0 */ + { + t[i] = x->v[i] + 0x1fe; + } + t[28] = x->v[28] + 0x1fc; + for (i = 29; i < 56; i++) + { + t[i] = x->v[i] + 0x1fe; + } + t[56] = 0; + for (i = 0; i < 57; i++) + r->v[i] = t[i] - y->v[i]; + reduce_add_sub(r); +} + +/* a slow version copied from sc448.c */ +void fe448_mul(fe448 *r, const fe448 *x, const fe448 *y) +{ + int i, j, carry; + crypto_uint32 t[114]; + for (i = 0; i < 114; i++) + t[i] = 0; + + for (i = 0; i < 57; i++) + for (j = 0; j < 57; j++) + t[i + j] += x->v[i] * y->v[j]; + + for (i = 0; i < 113; i++) + { + carry = t[i] >> 8; + t[i + 1] += carry; + t[i] &= 0xff; + } + + barrett_reduce(r, t); +} + +void fe448_square(fe448 *r, const fe448 *x) +{ + fe448_mul(r, x, x); +} + +void fe448_invert(fe448 *r, const fe448 *x) +{ + fe448 t0; + fe448 t1; + fe448 t2; + int i; + + fe448_square(&t0, x); + fe448_mul(&t0, &t0, x); /* 2^2 - 1 */ + fe448_square(&t0, &t0); /* 2^3 - 2 */ + fe448_mul(&t1, &t0, x); /* 2^3 - 1 */ + fe448_square(&t0, &t1); /* 2^4 - 2^1 */ + for (i = 0; i < 2; i++) + { + fe448_square(&t0, &t0); + } /* 2^6 - 2^3 */ + fe448_mul(&t1, &t1, &t0); /* 2^6 - 1 */ + fe448_square(&t0, &t1); /* 2^7 - 2^1 */ + for (i = 0; i < 5; i++) + { + fe448_square(&t0, &t0); + } /* 2^12 - 2^6 */ + fe448_mul(&t1, &t1, &t0); /* 2^12 - 1 */ + fe448_square(&t1, &t1); /* 2^13 - 2^1 */ + fe448_mul(&t1, &t1, x); /* 2^13 - 1 */ + fe448_square(&t0, &t1); /* 2^14 - 2^1 */ + for (i = 0; i < 12; i++) + { + fe448_square(&t0, &t0); + } /* 2^26 - 2^13 */ + fe448_mul(&t1, &t1, &t0); /* 2^26 - 1 */ + fe448_square(&t1, &t1); /* 2^26 - 2^1 */ + fe448_mul(&t1, &t1, x); /* 2^27 - 1 */ + fe448_square(&t0, &t1); /* 2^28 - 2^1 */ + for (i = 0; i < 26; i++) + { + fe448_square(&t0, &t0); + } /* 2^54 - 2^27 */ + fe448_mul(&t1, &t1, &t0); /* 2^54 - 1 */ + fe448_square(&t1, &t1); /* 2^55 - 2^1 */ + fe448_mul(&t1, &t1, x); /* 2^55 - 1 */ + fe448_square(&t0, &t1); /* 2^56 - 2^1 */ + for (i = 0; i < 54; i++) + { + fe448_square(&t0, &t0); + } /* 2^110 - 2^55 */ + fe448_mul(&t1, &t1, &t0); /* 2^110 - 1 */ + fe448_square(&t1, &t1); /* 2^111 - 2^1 */ + fe448_mul(&t1, &t1, x); /* 2^111 - 1 */ + fe448_square(&t0, &t1); /* 2^112 - 2^1 */ + for (i = 0; i < 110; i++) + { + fe448_square(&t0, &t0); + } /* 2^222 - 2^111 */ + fe448_mul(&t2, &t1, &t0); /* 2^222 - 1 */ + fe448_square(&t1, &t2); /* 2^223 - 2^1 */ + fe448_mul(&t1, &t1, x); /* 2^223 - 1 */ + fe448_square(&t0, &t1); /* 2^224 - 2^1 */ + for (i = 0; i < 222; i++) + { + fe448_square(&t0, &t0); + } /* 2^446 - 2^223 */ + fe448_mul(&t0, &t2, &t0); /* 2^446 - 2^222 - 1 */ + fe448_square(&t0, &t0); /* 2^447 - 2^223 - 2 */ + fe448_square(&t0, &t0); /* 2^448 - 2^224 - 4 */ + fe448_mul(r, &t0, x); /* 2^448 - 2^224 - 3 */ +} + +/* pow(2**446-2**222-1) */ +void fe448_pow446(fe448 *r, const fe448 *x) +{ +} @@ -0,0 +1,62 @@ +#ifndef FE448_H +#define FE448_H + +#include "defs.h" + +#define fe448 crypto_sign_ed448_ref_fe448 +#define fe448_freeze crypto_sign_ed448_ref_fe448_freeze +#define fe448_unpack crypto_sign_ed448_ref_fe448_unpack +#define fe448_pack crypto_sign_ed448_ref_fe448_pack +#define fe448_iszero crypto_sign_ed448_ref_fe448_iszero +#define fe448_iseq_vartime crypto_sign_ed448_ref_fe448_iseq_vartime +#define fe448_cmov crypto_sign_ed448_ref_fe448_cmov +#define fe448_setone crypto_sign_ed448_ref_fe448_setone +#define fe448_setzero crypto_sign_ed448_ref_fe448_setzero +#define fe448_neg crypto_sign_ed448_ref_fe448_neg +#define fe448_getparity crypto_sign_ed448_ref_fe448_getparity +#define fe448_add crypto_sign_ed448_ref_fe448_add +#define fe448_sub crypto_sign_ed448_ref_fe448_sub +#define fe448_mul crypto_sign_ed448_ref_fe448_mul +#define fe448_square crypto_sign_ed448_ref_fe448_square +#define fe448_invert crypto_sign_ed448_ref_fe448_invert +#define fe448_pow2523 crypto_sign_ed448_ref_fe448_pow2523 + +typedef struct +{ + crypto_uint32 v[57]; +} +fe448; + +void fe448_freeze(fe448 *r); + +void fe448_unpack(fe448 *r, const unsigned char x[57]); + +void fe448_pack(unsigned char r[57], const fe448 *x); + +int fe448_iszero(const fe448 *x); + +int fe448_iseq_vartime(const fe448 *x, const fe448 *y); + +void fe448_cmov(fe448 *r, const fe448 *x, unsigned char b); + +void fe448_setone(fe448 *r); + +void fe448_setzero(fe448 *r); + +void fe448_neg(fe448 *r, const fe448 *x); + +unsigned char fe448_getparity(const fe448 *x); + +void fe448_add(fe448 *r, const fe448 *x, const fe448 *y); + +void fe448_sub(fe448 *r, const fe448 *x, const fe448 *y); + +void fe448_mul(fe448 *r, const fe448 *x, const fe448 *y); + +void fe448_square(fe448 *r, const fe448 *x); + +void fe448_invert(fe448 *r, const fe448 *x); + +void fe448_pow446(fe448 *r, const fe448 *x); + +#endif @@ -0,0 +1,291 @@ +#include "sc448.h" + +/* order of base point of Ed448-Goldilocks: 2**446-13818066809895115352007386748515426880336692474882178609894547503885 */ + +static const crypto_uint32 m[57] = {0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D, 0x72, 0xC2, 0x6C, 0x21, + 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4, 0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00}; + +/* 256**114//m */ +static const crypto_uint32 mu[59] = {0x0A, 0xD0, 0xE0, 0xB0, 0x7B, 0x4A, 0xD5, 0xD6, 0x73, 0xC8, 0xAD, 0x0A, 0xA7, 0x23, 0xD7, 0xD8, + 0x33, 0xE9, 0xFD, 0x96, 0x9C, 0x12, 0x65, 0x4B, 0x12, 0xBB, 0x63, 0xC1, 0x5D, 0x33, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}; + +static crypto_uint32 lt(crypto_uint32 a, crypto_uint32 b) /* 16-bit inputs */ +{ + unsigned int x = a; + x -= (unsigned int)b; /* 0..65535: no; 4294901761..4294967295: yes */ + x >>= 31; /* 0: no; 1: yes */ + return x; +} + +/* Reduce coefficients of r before calling reduce_add_sub */ +static void reduce_add_sub(sc448 *r) +{ + crypto_uint32 pb = 0; + crypto_uint32 b; + crypto_uint32 mask; + int i; + unsigned char t[57]; + + for (i = 0; i < 57; i++) + { + pb += m[i]; + b = lt(r->v[i], pb); + t[i] = r->v[i] - pb + (b << 8); + pb = b; + } + mask = b - 1; + for (i = 0; i < 57; i++) + r->v[i] ^= mask & (r->v[i] ^ t[i]); +} + +/* Reduce coefficients of x before calling barrett_reduce */ +static void barrett_reduce(sc448 *r, const crypto_uint32 x[114]) +{ + /* See HAC, Alg. 14.42 */ + int i, j; + crypto_uint32 q2[116]; + crypto_uint32 *q3 = q2 + 58; + crypto_uint32 r1[58]; + crypto_uint32 r2[58]; + crypto_uint32 carry; + crypto_uint32 pb = 0; + crypto_uint32 b; + + for (i = 0; i < 116; ++i) + q2[i] = 0; + for (i = 0; i < 58; ++i) + r2[i] = 0; + + for (i = 0; i < 59; i++) + for (j = 0; j < 58; j++) + if (i + j >= 56) + q2[i + j] += mu[i] * x[j + 56]; + carry = q2[56] >> 8; + q2[57] += carry; + carry = q2[57] >> 8; + q2[58] += carry; + + for (i = 0; i < 58; i++) + r1[i] = x[i]; + for (i = 0; i < 57; i++) + for (j = 0; j < 58; j++) + if (i + j < 58) + r2[i + j] += m[i] * q3[j]; + + for (i = 0; i < 57; i++) + { + carry = r2[i] >> 8; + r2[i + 1] += carry; + r2[i] &= 0xff; + } + + for (i = 0; i < 57; i++) + { + pb += r2[i]; + b = lt(r1[i], pb); + r->v[i] = r1[i] - pb + (b << 8); + pb = b; + } + + /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 + * If so: Handle it here! + */ + + reduce_add_sub(r); + reduce_add_sub(r); + reduce_add_sub(r); + reduce_add_sub(r); +} + +void sc448_from57bytes(sc448 *r, const unsigned char x[57]) +{ + int i; + crypto_uint32 t[114]; + for (i = 0; i < 57; i++) + t[i] = x[i]; + for (i = 57; i < 114; ++i) + t[i] = 0; + barrett_reduce(r, t); +} + +void sc448_from114bytes(sc448 *r, const unsigned char x[114]) +{ + int i; + crypto_uint32 t[114]; + for (i = 0; i < 114; i++) + t[i] = x[i]; + barrett_reduce(r, t); +} + +void sc448_to57bytes(unsigned char r[57], const sc448 *x) +{ + int i; + for (i = 0; i < 57; i++) + r[i] = x->v[i]; +} + +int sc448_iszero_vartime(const sc448 *x) +{ + int i; + for (i = 0; i < 57; i++) + if (x->v[i] != 0) + return 0; + return 1; +} + +int sc448_lt_vartime(const sc448 *x, const sc448 *y) +{ + int i; + for (i = 56; i >= 0; i--) + { + if (x->v[i] < y->v[i]) + return 1; + if (x->v[i] > y->v[i]) + return 0; + } + return 0; +} + +void sc448_add(sc448 *r, const sc448 *x, const sc448 *y) +{ + int i, carry; + for (i = 0; i < 57; i++) + r->v[i] = x->v[i] + y->v[i]; + for (i = 0; i < 56; i++) + { + carry = r->v[i] >> 8; + r->v[i + 1] += carry; + r->v[i] &= 0xff; + } + reduce_add_sub(r); +} + +void sc448_sub_nored(sc448 *r, const sc448 *x, const sc448 *y) +{ + crypto_uint32 b = 0; + crypto_uint32 t; + int i; + for (i = 0; i < 57; i++) + { + t = x->v[i] - y->v[i] - b; + r->v[i] = t & 255; + b = (t >> 8) & 1; + } +} + +void sc448_mul(sc448 *r, const sc448 *x, const sc448 *y) +{ + int i, j, carry; + crypto_uint32 t[114]; + for (i = 0; i < 114; i++) + t[i] = 0; + + for (i = 0; i < 57; i++) + for (j = 0; j < 57; j++) + t[i + j] += x->v[i] * y->v[j]; + + /* Reduce coefficients */ + for (i = 0; i < 113; i++) + { + carry = t[i] >> 8; + t[i + 1] += carry; + t[i] &= 0xff; + } + + barrett_reduce(r, t); +} + /* not implemented yet */ +#if 0 +void sc25519_window3(signed char r[85], const sc25519 *s) +{ + char carry; + int i; + for (i = 0; i < 10; i++) + { + r[8 * i + 0] = s->v[3 * i + 0] & 7; + r[8 * i + 1] = (s->v[3 * i + 0] >> 3) & 7; + r[8 * i + 2] = (s->v[3 * i + 0] >> 6) & 7; + r[8 * i + 2] ^= (s->v[3 * i + 1] << 2) & 7; + r[8 * i + 3] = (s->v[3 * i + 1] >> 1) & 7; + r[8 * i + 4] = (s->v[3 * i + 1] >> 4) & 7; + r[8 * i + 5] = (s->v[3 * i + 1] >> 7) & 7; + r[8 * i + 5] ^= (s->v[3 * i + 2] << 1) & 7; + r[8 * i + 6] = (s->v[3 * i + 2] >> 2) & 7; + r[8 * i + 7] = (s->v[3 * i + 2] >> 5) & 7; + } + r[8 * i + 0] = s->v[3 * i + 0] & 7; + r[8 * i + 1] = (s->v[3 * i + 0] >> 3) & 7; + r[8 * i + 2] = (s->v[3 * i + 0] >> 6) & 7; + r[8 * i + 2] ^= (s->v[3 * i + 1] << 2) & 7; + r[8 * i + 3] = (s->v[3 * i + 1] >> 1) & 7; + r[8 * i + 4] = (s->v[3 * i + 1] >> 4) & 7; + + /* Making it signed */ + carry = 0; + for (i = 0; i < 84; i++) + { + r[i] += carry; + r[i + 1] += r[i] >> 3; + r[i] &= 7; + carry = r[i] >> 2; + r[i] -= carry << 3; + } + r[84] += carry; +} + +void sc25519_window5(signed char r[51], const sc25519 *s) +{ + char carry; + int i; + for (i = 0; i < 6; i++) + { + r[8 * i + 0] = s->v[5 * i + 0] & 31; + r[8 * i + 1] = (s->v[5 * i + 0] >> 5) & 31; + r[8 * i + 1] ^= (s->v[5 * i + 1] << 3) & 31; + r[8 * i + 2] = (s->v[5 * i + 1] >> 2) & 31; + r[8 * i + 3] = (s->v[5 * i + 1] >> 7) & 31; + r[8 * i + 3] ^= (s->v[5 * i + 2] << 1) & 31; + r[8 * i + 4] = (s->v[5 * i + 2] >> 4) & 31; + r[8 * i + 4] ^= (s->v[5 * i + 3] << 4) & 31; + r[8 * i + 5] = (s->v[5 * i + 3] >> 1) & 31; + r[8 * i + 6] = (s->v[5 * i + 3] >> 6) & 31; + r[8 * i + 6] ^= (s->v[5 * i + 4] << 2) & 31; + r[8 * i + 7] = (s->v[5 * i + 4] >> 3) & 31; + } + r[8 * i + 0] = s->v[5 * i + 0] & 31; + r[8 * i + 1] = (s->v[5 * i + 0] >> 5) & 31; + r[8 * i + 1] ^= (s->v[5 * i + 1] << 3) & 31; + r[8 * i + 2] = (s->v[5 * i + 1] >> 2) & 31; + + /* Making it signed */ + carry = 0; + for (i = 0; i < 50; i++) + { + r[i] += carry; + r[i + 1] += r[i] >> 5; + r[i] &= 31; + carry = r[i] >> 4; + r[i] -= carry << 5; + } + r[50] += carry; +} + +void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2) +{ + int i; + for (i = 0; i < 31; i++) + { + r[4 * i] = (s1->v[i] & 3) ^ ((s2->v[i] & 3) << 2); + r[4 * i + 1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2); + r[4 * i + 2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2); + r[4 * i + 3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2); + } + r[124] = (s1->v[31] & 3) ^ ((s2->v[31] & 3) << 2); + r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2); + r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2); +} +#endif @@ -0,0 +1,57 @@ +#ifndef SC448_H +#define SC448_H + +#include "defs.h" + +#define sc448 crypto_sign_ed448_ref_sc448 +#define sc448_from57bytes crypto_sign_ed448_ref_sc448_from57bytes +#define sc448_from114bytes crypto_sign_ed448_ref_sc448_from114bytes +#define sc448_to57bytes crypto_sign_ed448_ref_sc448_to57bytes +#define sc448_iszero_vartime crypto_sign_ed448_ref_sc448_iszero_vartime +#define sc448_isshort_vartime crypto_sign_ed448_ref_sc448_isshort_vartime +#define sc448_lt_vartime crypto_sign_ed448_ref_sc448_lt_vartime +#define sc448_add crypto_sign_ed448_ref_sc448_add +#define sc448_sub_nored crypto_sign_ed448_ref_sc448_sub_nored +#define sc448_mul crypto_sign_ed448_ref_sc448_mul +#define sc448_window3 crypto_sign_ed448_ref_sc448_window3 +#define sc448_window5 crypto_sign_ed448_ref_sc448_window5 +#define sc448_2interleave2 crypto_sign_ed448_ref_sc448_2interleave2 + +typedef struct +{ + crypto_uint32 v[57]; +} +sc448; + +void sc448_from57bytes(sc448 *r, const unsigned char x[57]); + +void sc448_from114bytes(sc448 *r, const unsigned char x[114]); + +void sc448_to57bytes(unsigned char r[57], const sc448 *x); + +int sc448_iszero_vartime(const sc448 *x); + +int sc448_isshort_vartime(const sc448 *x); + +int sc448_lt_vartime(const sc448 *x, const sc448 *y); + +void sc448_add(sc448 *r, const sc448 *x, const sc448 *y); + +void sc448_sub_nored(sc448 *r, const sc448 *x, const sc448 *y); + +void sc448_mul(sc448 *r, const sc448 *x, const sc448 *y); + +#if 0 +/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3 + * with r[i] in {-4,...,3} + */ +void sc448_window3(signed char r[85], const sc448 *s); + +/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5 + * with r[i] in {-16,...,15} + */ +void sc448_window5(signed char r[51], const sc448 *s); + +void sc448_2interleave2(unsigned char r[127], const sc448 *s1, const sc448 *s2); +#endif +#endif |
