From 92bd3cab63231103408fe8b81f8538f01a33335b Mon Sep 17 00:00:00 2001 From: pmvr Date: Thu, 4 Jun 2020 08:01:20 +0200 Subject: [PATCH] replaced softlinks --- mpy-modules/curve25519/Makefile | 15 +- mpy-modules/curve25519/arithmetic.c | 178 ++++++++++++++++- mpy-modules/curve25519/arithmetic.h | 14 +- mpy-modules/curve25519/ec.c | 292 +++++++++++++++++++++++++++- mpy-modules/curve25519/ec.h | 7 +- mpy-modules/curve25519/main.c | 57 +++++- mpy-modules/sha512/Makefile | 16 +- mpy-modules/sha512/main.c | 31 ++- mpy-modules/sha512/sha512.c | 196 ++++++++++++++++++- mpy-modules/sha512/sha512.h | 55 +++++- 10 files changed, 851 insertions(+), 10 deletions(-) mode change 120000 => 100644 mpy-modules/curve25519/Makefile mode change 120000 => 100644 mpy-modules/curve25519/arithmetic.c mode change 120000 => 100644 mpy-modules/curve25519/arithmetic.h mode change 120000 => 100644 mpy-modules/curve25519/ec.c mode change 120000 => 100644 mpy-modules/curve25519/ec.h mode change 120000 => 100644 mpy-modules/curve25519/main.c mode change 120000 => 100644 mpy-modules/sha512/Makefile mode change 120000 => 100644 mpy-modules/sha512/main.c mode change 120000 => 100644 mpy-modules/sha512/sha512.c mode change 120000 => 100644 mpy-modules/sha512/sha512.h diff --git a/mpy-modules/curve25519/Makefile b/mpy-modules/curve25519/Makefile deleted file mode 120000 index bd6786a..0000000 --- a/mpy-modules/curve25519/Makefile +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/Makefile \ No newline at end of file diff --git a/mpy-modules/curve25519/Makefile b/mpy-modules/curve25519/Makefile new file mode 100644 index 0000000..569929a --- /dev/null +++ b/mpy-modules/curve25519/Makefile @@ -0,0 +1,14 @@ +# Location of top-level MicroPython directory +MPY_DIR = $(HOME)/github/micropython + +# Name of module +MOD = curve25519 + +# Source files (.c or .py) +SRC = main.c arithmetic.c ec.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = armv7m + +# Include to get the rules for compiling and linking the module +include $(MPY_DIR)/py/dynruntime.mk diff --git a/mpy-modules/curve25519/arithmetic.c b/mpy-modules/curve25519/arithmetic.c deleted file mode 120000 index ff8c905..0000000 --- a/mpy-modules/curve25519/arithmetic.c +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/arithmetic.c \ No newline at end of file diff --git a/mpy-modules/curve25519/arithmetic.c b/mpy-modules/curve25519/arithmetic.c new file mode 100644 index 0000000..3842a2b --- /dev/null +++ b/mpy-modules/curve25519/arithmetic.c @@ -0,0 +1,177 @@ +#include "py/dynruntime.h" + + +uint32_t add_zxy(uint32_t *z, uint32_t *x, uint32_t *y) { + uint32_t carry; + __asm__ volatile ( + "LDMIA %1!, {r3-r6}\n" + "LDMIA %2!, {r7-r10}\n" + "ADDS r3, r3, r7\n" + "ADCS r4, r4, r8\n" + "ADCS r5, r5, r9\n" + "ADCS r6, r6, r10\n" + "STMIA %3!, {r3-r6}\n" + "LDMIA %1!, {r3-r6}\n" + "LDMIA %2!, {r7-r10}\n" + "ADCS r3, r3, r7\n" + "ADCS r4, r4, r8\n" + "ADCS r5, r5, r9\n" + "ADCS r6, r6, r10\n" + "STMIA %3!, {r3-r6}\n" + "LDMIA %1, {r3}\n" + "LDMIA %2, {r7}\n" + "ADCS r3, r3, r7\n" + "STMIA %3, {r3}\n" + "MOV %0, 0\n" + "ADCS %0, %0, 0\n" + : "=r" (carry) : "r" (x), "r" (y), "r" (z) : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + return carry; +} + + +uint32_t sub_zxy(uint32_t *z, uint32_t *x, uint32_t *y) { + uint32_t carry; + __asm__ volatile ( + "LDMIA %1!, {r3-r6}\n" + "LDMIA %2!, {r7-r10}\n" + "SUBS r3, r3, r7\n" + "SBCS r4, r4, r8\n" + "SBCS r5, r5, r9\n" + "SBCS r6, r6, r10\n" + "STMIA %3!, {r3-r6}\n" + "LDMIA %1!, {r3-r6}\n" + "LDMIA %2!, {r7-r10}\n" + "SBCS r3, r3, r7\n" + "SBCS r4, r4, r8\n" + "SBCS r5, r5, r9\n" + "SBCS r6, r6, r10\n" + "STMIA %3!, {r3-r6}\n" + "LDMIA %1, {r3}\n" + "LDMIA %2, {r7}\n" + "SBCS r3, r3, r7\n" + "STMIA %3, {r3}\n" + "MOV %0, 0\n" + "ADCS %0, %0, 0\n" + : "=r" (carry) : "r" (x), "r" (y), "r" (z) : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + return carry; +} + + +void add_zxy_mod_p(uint32_t *z, uint32_t *x, uint32_t *y, uint32_t *p) { + uint32_t z1[9], z2[9]; + uint32_t* ret[2] = {z1, z2}; + add_zxy(z1, x, y); + uint32_t c = sub_zxy(z2, z1, p); // carry not set if negative + for (int i=0; i<9; i++) z[i] = ret[c][i]; +} + + +void mul_zxy(uint32_t *z, uint32_t *x, uint32_t y) { + __asm__ volatile ( + // 0 + "LDMIA %0!, {r3}\n" + "UMULL r5, r6, r3, %1\n" + "STMIA %2!, {r5}\n" + // 1 + "LDMIA %0!, {r3}\n" + "MOV r5, 0\n" + "UMLAL r6, r5, r3, %1\n" + "STMIA %2!, {r6}\n" + // 2 + "LDMIA %0!, {r3}\n" + "MOV r6, 0\n" + "UMLAL r5, r6, r3, %1\n" + "STMIA %2!, {r5}\n" + // 3 + "LDMIA %0!, {r3}\n" + "MOV r5, 0\n" + "UMLAL r6, r5, r3, %1\n" + "STMIA %2!, {r6}\n" + // 4 + "LDMIA %0!, {r3}\n" + "MOV r6, 0\n" + "UMLAL r5, r6, r3, %1\n" + "STMIA %2!, {r5}\n" + // 5 + "LDMIA %0!, {r3}\n" + "MOV r5, 0\n" + "UMLAL r6, r5, r3, %1\n" + "STMIA %2!, {r6}\n" + // 6 + "LDMIA %0!, {r3}\n" + "MOV r6, 0\n" + "UMLAL r5, r6, r3, %1\n" + "STMIA %2!, {r5}\n" + // 7 + "LDMIA %0!, {r3}\n" + "MOV r5, 0\n" + "UMLAL r6, r5, r3, %1\n" + "STMIA %2!, {r6}\n" + "STMIA %2, {r5}\n" + : : "r" (x), "r" (y), "r" (z) : "r3", "r5", "r6" + ); +} + + +void mul_zx0y0(uint32_t *z, uint32_t x, uint32_t y) { + __asm__ volatile ( + // 0 + "UMULL r5, r6, %0, %1\n" + "STMIA %2!, {r5}\n" + "STMIA %2!, {r6}\n" + "MOV r5, 0\n" + "MOV r6, 0\n" + "STMIA %2!, {r5, r6}\n" + "STMIA %2!, {r5, r6}\n" + "STMIA %2!, {r5, r6}\n" + "STMIA %2, {r5}\n" + : : "r" (x), "r" (y), "r" (z) : "r5", "r6" + ); +} + + +void mont_mul_zxy_mod_p(uint32_t *z, uint32_t *x, uint32_t *y, uint32_t *p) { + // see Alg. 14.36 HoAC + // -m^(-1) mod b is 678152731 for curve25519 + uint32_t u, carry; + uint32_t tmp[9], a[9]; + uint32_t* ret[2] = {a, tmp}; + + for (int i=0; i<9; i++) a[i] = 0; + for (int i=0; i<8; i++) { + u = (a[0] + x[i] * y[0]) * 678152731; + mul_zxy(tmp, y, x[i]); + carry = add_zxy(a, a, tmp); + mul_zxy(tmp, p, u); + carry += add_zxy(a, a, tmp); // A <- (A + xi y + u m) / b + for (int j=0; j<8; j++) a[j] = a[j+1]; + a[8] = carry; + } + uint32_t c = sub_zxy(tmp, a, p); // carry not set if negative + for (int i=0; i<9; i++) z[i] = ret[c][i]; +} + + +void mont_mul_zxy0_mod_p(uint32_t *z, uint32_t *x, uint32_t y, uint32_t *p) { + // see Alg. 14.36 HoAC + // -m^(-1) mod b is 678152731 for curve25519 + uint32_t u, carry; + uint32_t tmp[9], a[9]; + uint32_t* ret[2] = {a, tmp}; + + for (int i=0; i<9; i++) a[i] = 0; + for (int i=0; i<8; i++) { + u = (a[0] + x[i] * y) * 678152731; + mul_zx0y0(tmp, x[i], y); + carry = add_zxy(a, a, tmp); + mul_zxy(tmp, p, u); + carry += add_zxy(a, a, tmp); // A <- (A + xi y + u m) / b + for (int j=0; j<8; j++) a[j] = a[j+1]; + a[8] = carry; + } + uint32_t c = sub_zxy(tmp, a, p); // carry not set if negative + for (int i=0; i<9; i++) z[i] = ret[c][i]; +} + diff --git a/mpy-modules/curve25519/arithmetic.h b/mpy-modules/curve25519/arithmetic.h deleted file mode 120000 index bed2478..0000000 --- a/mpy-modules/curve25519/arithmetic.h +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/arithmetic.h \ No newline at end of file diff --git a/mpy-modules/curve25519/arithmetic.h b/mpy-modules/curve25519/arithmetic.h new file mode 100644 index 0000000..0fd8464 --- /dev/null +++ b/mpy-modules/curve25519/arithmetic.h @@ -0,0 +1,13 @@ +#ifndef __arithmetic__ +#define __arithmetic__ + +void shift_right(uint32_t *x); +uint32_t add_zxy(uint32_t *z, uint32_t *x, uint32_t *y); +uint32_t sub_zxy(uint32_t *z, uint32_t *x, uint32_t *y); +void add_zxy_mod_p(uint32_t *z, uint32_t *x, uint32_t *y, uint32_t *p); +void mul_zxy(uint32_t *z, uint32_t *x, uint32_t y); +void mul_zx0y0(uint32_t *z, uint32_t x, uint32_t y); +void mont_mul_zxy_mod_p(uint32_t *z, uint32_t *x, uint32_t *y, uint32_t *p); +void mont_mul_zxy0_mod_p(uint32_t *z, uint32_t *x, uint32_t y, uint32_t *p); + +#endif diff --git a/mpy-modules/curve25519/ec.c b/mpy-modules/curve25519/ec.c deleted file mode 120000 index baffe4b..0000000 --- a/mpy-modules/curve25519/ec.c +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/ec.c \ No newline at end of file diff --git a/mpy-modules/curve25519/ec.c b/mpy-modules/curve25519/ec.c new file mode 100644 index 0000000..e1eac9a --- /dev/null +++ b/mpy-modules/curve25519/ec.c @@ -0,0 +1,291 @@ +#include "py/dynruntime.h" +#include "arithmetic.h" +#include "ec.h" + +const uint32_t a24R = 0x468ba6; +const uint32_t p[9] = {0x00000000, 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffed}; +const uint32_t pR2 = 0x5a4; +const uint32_t R = 38; +const uint32_t sqrt_minus_486664R[9] = {0x00000000, 0x4038adb9, 0xa83f001e, 0xc1bcaf57, 0x688c332e, 0xa9fa8eee, 0xcb6e1095, 0xa7ab4e9e, 0x1baf4abd}; + +struct curve { + uint32_t a24; + uint32_t p[9]; + uint32_t pR2; +}; + +struct curve Curve; + +void random_z(uint32_t *z) { + // TODO: a true random source should be provided + for (uint32_t i=0; i<8; i++) z[i] = 0xC3A50FE1; + z[8] = 0; + z[7] &= 0x7fffffff; +} + + +void ini_curve() { + Curve.a24 = a24R; + Curve.pR2 = pR2; + for (int i=0; i<9; i++) { + Curve.p[i] = p[8-i]; + } +} + + +void to_Montgomery(uint32_t *x) { + uint32_t s[9]; + mont_mul_zxy0_mod_p(s, x, Curve.pR2, Curve.p); + for (uint32_t i=0;i<9;i++) x[i] = s[i]; +} + + +void from_Montgomery(uint32_t *x) { + uint32_t s[9]; + mont_mul_zxy0_mod_p(s, x, 1, Curve.p); + for (uint32_t i=0;i<9;i++) x[i] = s[i]; +} + + +void mod_inverse(uint32_t *z_inv, uint32_t *z) { + uint32_t z2[9]; + uint32_t z9[9]; + uint32_t z11[9]; + uint32_t z2_5_0[9]; + uint32_t z2_10_0[9]; + uint32_t z2_20_0[9]; + uint32_t z2_50_0[9]; + uint32_t z2_100_0[9]; + uint32_t t0[9]; + uint32_t t1[9]; + uint32_t i; + + mont_mul_zxy_mod_p(z2, z, z, Curve.p); // 2 + mont_mul_zxy_mod_p(t1, z2, z2, Curve.p); // 4 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 8 + mont_mul_zxy_mod_p(z9, t0, z, Curve.p); // 9 + mont_mul_zxy_mod_p(z11, z9, z2, Curve.p); // 11 + mont_mul_zxy_mod_p(t0, z11, z11, Curve.p); // 22 + mont_mul_zxy_mod_p(z2_5_0, t0, z9, Curve.p); // 31 = 2^5 - 2^0 + + mont_mul_zxy_mod_p(t0, z2_5_0, z2_5_0, Curve.p); // 2^6 - 2^1 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^7 - 2^2 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^8 - 2^3 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^9 - 2^4 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^10 - 2^5 + mont_mul_zxy_mod_p(z2_10_0, t0, z2_5_0, Curve.p); // 2^10 - 2^0 + + mont_mul_zxy_mod_p(t0, z2_10_0, z2_10_0, Curve.p); // 2^11 - 2^1 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^12 - 2^2 + for (i = 2; i < 10; i += 2) { + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + } // 2^20 - 2^10 + mont_mul_zxy_mod_p(z2_20_0, t1, z2_10_0, Curve.p); // 2^20 - 2^0 + + mont_mul_zxy_mod_p(t0, z2_20_0, z2_20_0, Curve.p); // 2^21 - 2^1 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^22 - 2^2 + for (i = 2; i < 20; i += 2) { + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + } // 2^40 - 2^20 + mont_mul_zxy_mod_p(t0, t1, z2_20_0, Curve.p); // 2^40 - 2^0 + + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^41 - 2^1 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^42 - 2^2 + for (i = 2; i < 10; i += 2) { + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + } // 2^50 - 2^10 + mont_mul_zxy_mod_p(z2_50_0, t0, z2_10_0, Curve.p); // 2^50 - 2^0 + + mont_mul_zxy_mod_p(t0, z2_50_0, z2_50_0, Curve.p); // 2^51 - 2^1 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^42 - 2^2 + for (i = 2; i < 50; i += 2) { + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + } // 2^100 - 2^50 + mont_mul_zxy_mod_p(z2_100_0, t1, z2_50_0, Curve.p); // 2^100 - 2^0 + + mont_mul_zxy_mod_p(t1, z2_100_0, z2_100_0, Curve.p); // 2^101 - 2^1 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^102 - 2^2 + for (i = 2; i < 100; i += 2) { + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + } // 2^200 - 2^100 + mont_mul_zxy_mod_p(t1, t0, z2_100_0, Curve.p); // 2^200 - 2^0 + + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^201 - 2^1 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^102 - 2^2 + for (i = 2; i < 50; i += 2) { + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); + } // 2^250 - 2^50 + mont_mul_zxy_mod_p(t0, t1, z2_50_0, Curve.p); // 2^250 - 2^0 + + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^251 - 2^1 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^252 - 2^2 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^253 - 2^3 + mont_mul_zxy_mod_p(t0, t1, t1, Curve.p); // 2^254 - 2^4 + mont_mul_zxy_mod_p(t1, t0, t0, Curve.p); // 2^255 - 2^5 + mont_mul_zxy_mod_p(z_inv, t1, z11, Curve.p); // 2^255 - 21 +} + +void recover_y(uint32_t *x, uint32_t *y, uint32_t *z, uint32_t *xp, uint32_t *yp, uint32_t *xq, uint32_t *zq, uint32_t *xpq, uint32_t *zpq) { + // https://eprint.iacr.org/2017/212.pdf + uint32_t AR = 18493156; + uint32_t v1[9], v2[9], v3[9], v4[9], s[9], t[9]; + + mont_mul_zxy_mod_p(v1, xp, zq, Curve.p); + add_zxy_mod_p(v2, xq, v1, Curve.p); + sub_zxy(v3, Curve.p, v1); + add_zxy_mod_p(v3, xq, v3, Curve.p); + mont_mul_zxy_mod_p(t, v3, v3, Curve.p); + mont_mul_zxy_mod_p(v3, t, xpq, Curve.p); + mont_mul_zxy0_mod_p(v1, zq, AR, Curve.p); + add_zxy_mod_p(v1, v1, v1, Curve.p); + add_zxy_mod_p(v2, v2, v1, Curve.p); + mont_mul_zxy_mod_p(v4, xp, xq, Curve.p); + add_zxy_mod_p(v4, v4, zq, Curve.p); + mont_mul_zxy_mod_p(s, v2, v4, Curve.p); + mont_mul_zxy_mod_p(t, v1, zq, Curve.p); + sub_zxy(t, Curve.p, t); + add_zxy_mod_p(s, s, t, Curve.p); + mont_mul_zxy_mod_p(v2, s, zpq, Curve.p); + sub_zxy(v3, Curve.p, v3); + add_zxy_mod_p(y, v2, v3, Curve.p); + add_zxy_mod_p(v1, yp, yp, Curve.p); + mont_mul_zxy_mod_p(s, v1, zq, Curve.p); + mont_mul_zxy_mod_p(v1, s, zpq, Curve.p); + mont_mul_zxy_mod_p(x, v1, xq, Curve.p); + mont_mul_zxy_mod_p(z, v1, zq, Curve.p); +} + + +void montgomery2edward(uint32_t *x, uint32_t *y, uint32_t *u, uint32_t *v) { + // (x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1)) + uint32_t s[9], t[9], w[9]; + + for (uint32_t i=1; i<9; i++) t[i] = 0; + t[0] = R; // 1*R + add_zxy_mod_p(s, u, t, Curve.p); // s = u+1 + mont_mul_zxy_mod_p(w, s, v, Curve.p); + mod_inverse(w, w); // w = (u+1)^(-1) * v^(-1) + sub_zxy(t, Curve.p, t); // t = -1*R + add_zxy_mod_p(y, u, t, Curve.p); // y = u-1 + mont_mul_zxy_mod_p(x, y, w, Curve.p); // x = (u-1)/((u+1) * v) + mont_mul_zxy_mod_p(y, x, v, Curve.p); + for (uint32_t i=0; i<9; i++) t[i] = sqrt_minus_486664R[8-i]; + mont_mul_zxy_mod_p(x, t, w, Curve.p); + mont_mul_zxy_mod_p(t, x, s, Curve.p); + mont_mul_zxy_mod_p(x, t, u, Curve.p); +} + + +void cswap(uint32_t swap, uint32_t **x, uint32_t **y) { + // https://tools.ietf.org/html/rfc7748 sec. 5 + __asm__ volatile ( + "LDMIA %1, {r3}\n" + "LDMIA %2, {r4}\n" + "RSB r5, %0, 0\n" + "EOR r6, r3, r4\n" + "AND r5, r5, r6\n" + "EOR r3, r3, r5\n" + "EOR r4, r4, r5\n" + "STMIA %1, {r3}\n" + "STMIA %2, {r4}\n" + : : "r" (swap), "r" (x), "r" (y) : "r3", "r4", "r5", "r6" + ); +} + +void X25519(uint32_t *q, uint32_t *r, uint8_t *k, uint32_t *u, uint32_t *v, uint8_t toEdward) { + // cpmputes q = k * u + uint32_t x1[9], x[2*9], z[2*9]; + uint32_t *x2 = x; uint32_t *x3 = x+9; + uint32_t *z2 = z; uint32_t *z3 = z+9; + uint8_t swap, kt, kw; + uint32_t A[9], AA[9], B[9], BB[9], C[9], D[9], E[9], DA[9], CB[9]; + + ini_curve(); + + // x1, z1 = u, 1 + // x2, z2 = 1, 0 + // x3, z3 = u, 1 + random_z(z3); + random_z(x2); + for (uint32_t i=0; i<8; i++) { + A[i] = u[i]; + z2[i] = 0; + } + z2[8] = A[8] = 0; + to_Montgomery(A); + for (uint32_t i=0; i<9; i++) x1[i] = A[i]; + mont_mul_zxy_mod_p(x3, A, z3, Curve.p); + + swap = 0; + kw = k[31]; + for (int32_t t=254; t>=0; t--) { + if (t % 8 == 7) kw = k[t / 8]; + kt = (kw >> (t % 8)) & 1; + swap ^= kt; + // conditional swap + cswap(swap, &x2, &x3); + cswap(swap, &z2, &z3); + swap = kt; + + add_zxy_mod_p(A, x2, z2, Curve.p); + mont_mul_zxy_mod_p(AA, A, A, Curve.p); + sub_zxy(B, Curve.p, z2); + add_zxy_mod_p(B, x2, B, Curve.p); + mont_mul_zxy_mod_p(BB, B, B, Curve.p); + sub_zxy(E, Curve.p, BB); + add_zxy_mod_p(E, AA, E, Curve.p); + add_zxy_mod_p(C, x3, z3, Curve.p); + sub_zxy(D, Curve.p, z3); + add_zxy_mod_p(D, x3, D, Curve.p); + mont_mul_zxy_mod_p(DA, D, A, Curve.p); + mont_mul_zxy_mod_p(CB, C, B, Curve.p); + add_zxy_mod_p(A, DA, CB, Curve.p); + mont_mul_zxy_mod_p(x3, A, A, Curve.p); + sub_zxy(A, Curve.p, CB); + add_zxy_mod_p(A, DA, A, Curve.p); + mont_mul_zxy_mod_p(B, A, A, Curve.p); + mont_mul_zxy_mod_p(z3, x1, B, Curve.p); + mont_mul_zxy_mod_p(x2, AA, BB, Curve.p); + mont_mul_zxy0_mod_p(A, E, Curve.a24, Curve.p); + add_zxy_mod_p(AA, AA, A, Curve.p); + mont_mul_zxy_mod_p(z2, E, AA, Curve.p); + } + // conditional swap + cswap(swap, &x2, &x3); + cswap(swap, &z2, &z3); + if (r && v) { + // compute y-coordinate + for (uint32_t i=0; i<8; i++) { + AA[i] = u[i]; + BB[i] = v[i]; + } + AA[8] = BB[8] = 0; + to_Montgomery(AA); + to_Montgomery(BB); + recover_y(A, B, C, AA, BB, x2, z2, x3, z3); + mod_inverse(C, C); + mont_mul_zxy_mod_p(q, A, C, Curve.p); + mont_mul_zxy_mod_p(r, B, C, Curve.p); + if (toEdward) { + for (uint32_t i=0; i<9; i++) { + A[i] = q[i]; + B[i] = r[i]; + } + montgomery2edward(q, r, A, B); + } + from_Montgomery(q); + from_Montgomery(r); + } else { + // compute x-only + // compute z2^(-1) = z2^{p-2} + mod_inverse(A, z2); + mont_mul_zxy_mod_p(q, x2, A, Curve.p); + from_Montgomery(q); + } +} diff --git a/mpy-modules/curve25519/ec.h b/mpy-modules/curve25519/ec.h deleted file mode 120000 index 4e742e0..0000000 --- a/mpy-modules/curve25519/ec.h +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/ec.h \ No newline at end of file diff --git a/mpy-modules/curve25519/ec.h b/mpy-modules/curve25519/ec.h new file mode 100644 index 0000000..f5865df --- /dev/null +++ b/mpy-modules/curve25519/ec.h @@ -0,0 +1,6 @@ +#ifndef __ec__ +#define __ec__ + +void X25519(uint32_t *q, uint32_t *r, uint8_t *k, uint32_t *u, uint32_t *v, uint8_t toEdward); + +#endif diff --git a/mpy-modules/curve25519/main.c b/mpy-modules/curve25519/main.c deleted file mode 120000 index 65072f8..0000000 --- a/mpy-modules/curve25519/main.c +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/main.c \ No newline at end of file diff --git a/mpy-modules/curve25519/main.c b/mpy-modules/curve25519/main.c new file mode 100644 index 0000000..ce96bee --- /dev/null +++ b/mpy-modules/curve25519/main.c @@ -0,0 +1,56 @@ + +// Include the header file to get access to the MicroPython API +#include "py/dynruntime.h" +#include "arithmetic.h" +#include "ec.h" + + +// This is the function which will be called from Python +STATIC mp_obj_t x25519(mp_obj_t k, mp_obj_t u) { + mp_buffer_info_t bufinfo_k, bufinfo_u; + + mp_get_buffer_raise(k, &bufinfo_k, MP_BUFFER_READ); + mp_get_buffer_raise(u, &bufinfo_u, MP_BUFFER_READ); + + uint32_t q[9]; + X25519(q, 0, bufinfo_k.buf, (uint32_t*)bufinfo_u.buf, 0, 0); + + return mp_obj_new_bytes((uint8_t *)q, 8*4); +} +// Define a Python reference to the function above +STATIC MP_DEFINE_CONST_FUN_OBJ_2(x25519_obj, x25519); + + +// This is the function which will be called from Python +STATIC mp_obj_t x25519_ed(mp_obj_t k, mp_obj_t u, mp_obj_t v) { + mp_obj_t items[2]; + mp_buffer_info_t bufinfo_k, bufinfo_u, bufinfo_v; + + mp_get_buffer_raise(k, &bufinfo_k, MP_BUFFER_READ); + mp_get_buffer_raise(u, &bufinfo_u, MP_BUFFER_READ); + mp_get_buffer_raise(v, &bufinfo_v, MP_BUFFER_READ); + + uint32_t q[9], r[9]; + X25519(q, r, bufinfo_k.buf, (uint32_t*)bufinfo_u.buf, (uint32_t*)bufinfo_v.buf, 1); + + items[0] = mp_obj_new_bytes((uint8_t *)q, 8*4); + items[1] = mp_obj_new_bytes((uint8_t *)r, 8*4); + return mp_obj_new_tuple(2, items); +} +// Define a Python reference to the function above +STATIC MP_DEFINE_CONST_FUN_OBJ_3(x25519_ed_obj, x25519_ed); + + +// This is the entry point and is called when the module is imported +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // This must be first, it sets up the globals dict and other things + MP_DYNRUNTIME_INIT_ENTRY + + // Make the function available in the module's namespace + mp_store_global(MP_QSTR_x25519, MP_OBJ_FROM_PTR(&x25519_obj)); + // Make the function available in the module's namespace + mp_store_global(MP_QSTR_x25519_ed, MP_OBJ_FROM_PTR(&x25519_ed_obj)); + + // This must be last, it restores the globals dict + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/mpy-modules/sha512/Makefile b/mpy-modules/sha512/Makefile deleted file mode 120000 index 5a90d7a..0000000 --- a/mpy-modules/sha512/Makefile +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/Makefile \ No newline at end of file diff --git a/mpy-modules/sha512/Makefile b/mpy-modules/sha512/Makefile new file mode 100644 index 0000000..1f89de4 --- /dev/null +++ b/mpy-modules/sha512/Makefile @@ -0,0 +1,15 @@ +# Location of top-level MicroPython directory +MPY_DIR = $(HOME)/github/micropython + +# Name of module +MOD = sha512 + +# Source files (.c or .py) +SRC = main.c sha512.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = armv7m + + +# Include to get the rules for compiling and linking the module +include $(MPY_DIR)/py/dynruntime.mk diff --git a/mpy-modules/sha512/main.c b/mpy-modules/sha512/main.c deleted file mode 120000 index dcb926c..0000000 --- a/mpy-modules/sha512/main.c +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/main.c \ No newline at end of file diff --git a/mpy-modules/sha512/main.c b/mpy-modules/sha512/main.c new file mode 100644 index 0000000..be55f68 --- /dev/null +++ b/mpy-modules/sha512/main.c @@ -0,0 +1,30 @@ + +// Include the header file to get access to the MicroPython API +#include "py/dynruntime.h" +#include "sha512.h" + + +// This is the function which will be called from Python, as factorial(x) +STATIC mp_obj_t digest(mp_obj_t data) { + mp_buffer_info_t bufinfo_data; + uint8_t out[64]; + + mp_get_buffer_raise(data, &bufinfo_data, MP_BUFFER_READ); + + sha512_simple(bufinfo_data.buf, bufinfo_data.len, out); + return mp_obj_new_bytes(out, 64); +} +// Define a Python reference to the function above +STATIC MP_DEFINE_CONST_FUN_OBJ_1(digest_obj, digest); + +// This is the entry point and is called when the module is imported +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + // This must be first, it sets up the globals dict and other things + MP_DYNRUNTIME_INIT_ENTRY + + // Make the function available in the module's namespace + mp_store_global(MP_QSTR_digest, MP_OBJ_FROM_PTR(&digest_obj)); + + // This must be last, it restores the globals dict + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/mpy-modules/sha512/sha512.c b/mpy-modules/sha512/sha512.c deleted file mode 120000 index d4dcade..0000000 --- a/mpy-modules/sha512/sha512.c +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/sha512.c \ No newline at end of file diff --git a/mpy-modules/sha512/sha512.c b/mpy-modules/sha512/sha512.c new file mode 100644 index 0000000..6ecc4f8 --- /dev/null +++ b/mpy-modules/sha512/sha512.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Arttu Hynninen + * Licensed under the MIT License. See the LICENSE file for the full text. + */ + +#include +#include "sha512.h" + +#pragma GCC diagnostic ignored "-Wimplicit-function-declaration" +#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#pragma GCC optimize 0 + +#define GET_UINT64(b) ( \ + ((uint64_t)(b)[0] << 56) | \ + ((uint64_t)(b)[1] << 48) | \ + ((uint64_t)(b)[2] << 40) | \ + ((uint64_t)(b)[3] << 32) | \ + ((uint64_t)(b)[4] << 24) | \ + ((uint64_t)(b)[5] << 16) | \ + ((uint64_t)(b)[6] << 8) | \ + ((uint64_t)(b)[7] )) + +#define PUT_UINT64(dst, x) { \ + (dst)[0] = (x) >> 56; \ + (dst)[1] = (x) >> 48; \ + (dst)[2] = (x) >> 40; \ + (dst)[3] = (x) >> 32; \ + (dst)[4] = (x) >> 24; \ + (dst)[5] = (x) >> 16; \ + (dst)[6] = (x) >> 8; \ + (dst)[7] = (x); } + +#define ROTR(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ ((x) >> 7)) +#define S1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ ((x) >> 6)) + +#define T0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) +#define T1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) + +#define CH(a, b, c) (((a) & (b)) ^ ((~(a)) & (c))) +#define MAJ(a, b, c) (((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))) +#define WW(i) (w[i] = w[i - 16] + S0(w[i - 15]) + w[i - 7] + S1(w[i - 2])) + +#define ROUND(a, b, c, d, e, f, g, h, k, w) { \ + uint64_t tmp0 = h + T1(e) + CH(e, f, g) + k + w; \ + uint64_t tmp1 = T0(a) + MAJ(a, b, c); \ + h = tmp0 + tmp1; \ + d += tmp0; } + + +void memcpy(uint8_t *dest, const uint8_t *src, uint32_t n) { + while (n-- > 0) *(dest++) = *(src++); +} + +void memset(uint8_t *dest, uint8_t b, uint32_t n) { + while (n-- > 0) *(dest++) = b; +} + +void sha512_init(sha512_ctx *ctx) +{ + sha512_ctx tmp = SHA512_INIT; + *ctx = tmp; +} + +void sha512_chunk(sha512_ctx *ctx, const uint8_t chunk [128]) +{ + const uint64_t rk [80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, + 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, + 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, + 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, + 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, + 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; + + uint64_t w [64]; + uint64_t a, b, c, d, e, f, g, h; + + int i; + + for (i = 0; i < 16; i++) + w[i] = GET_UINT64(&chunk[8 * i]); + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 16; i += 8) { + ROUND(a, b, c, d, e, f, g, h, rk[i ], w[i ]); + ROUND(h, a, b, c, d, e, f, g, rk[i + 1], w[i + 1]); + ROUND(g, h, a, b, c, d, e, f, rk[i + 2], w[i + 2]); + ROUND(f, g, h, a, b, c, d, e, rk[i + 3], w[i + 3]); + ROUND(e, f, g, h, a, b, c, d, rk[i + 4], w[i + 4]); + ROUND(d, e, f, g, h, a, b, c, rk[i + 5], w[i + 5]); + ROUND(c, d, e, f, g, h, a, b, rk[i + 6], w[i + 6]); + ROUND(b, c, d, e, f, g, h, a, rk[i + 7], w[i + 7]); + } + + for (i = 16; i < 80; i += 8) { + ROUND(a, b, c, d, e, f, g, h, rk[i ], WW(i )); + ROUND(h, a, b, c, d, e, f, g, rk[i + 1], WW(i + 1)); + ROUND(g, h, a, b, c, d, e, f, rk[i + 2], WW(i + 2)); + ROUND(f, g, h, a, b, c, d, e, rk[i + 3], WW(i + 3)); + ROUND(e, f, g, h, a, b, c, d, rk[i + 4], WW(i + 4)); + ROUND(d, e, f, g, h, a, b, c, rk[i + 5], WW(i + 5)); + ROUND(c, d, e, f, g, h, a, b, rk[i + 6], WW(i + 6)); + ROUND(b, c, d, e, f, g, h, a, rk[i + 7], WW(i + 7)); + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + +void sha512_process(sha512_ctx *ctx, const uint8_t *data, uint32_t length) +{ + ctx->len += length; + + if (ctx->buflen != 0 && ctx->buflen + length >= 128) { + int blen = 128 - ctx->buflen; + memcpy(ctx->buffer + ctx->buflen, data, blen); + sha512_chunk(ctx, ctx->buffer); + data += blen; + length -= blen; + ctx->buflen = 0; + } + + while (length >= 128) { + sha512_chunk(ctx, data); + data += 128; + length -= 128; + } + + if (length) { + memcpy(ctx->buffer + ctx->buflen, data, length); + ctx->buflen += length; + } +} + +void sha512_final(sha512_ctx *ctx, uint8_t out [64]) +{ + const uint8_t fill [112] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + uint32_t flen = (ctx->buflen < 112) ? 112 - ctx->buflen : 240 - ctx->buflen; + uint8_t buf [16]; + uint64_t hi_len = (uint64_t)(ctx->len >> 61); + uint64_t lo_len = (uint64_t)(ctx->len << 3); + + int i; + + PUT_UINT64(&buf[0], hi_len); + PUT_UINT64(&buf[8], lo_len); + + sha512_process(ctx, fill, flen); + sha512_process(ctx, buf, 16); + + for (i = 0; i < 8; i++) + PUT_UINT64(&out[8 * i], ctx->state[i]); + + memset((uint8_t*)ctx, 0, sizeof(sha512_ctx)); +} + +void sha512_simple(const uint8_t *data, uint32_t length, uint8_t out [64]) +{ + sha512_ctx ctx = SHA512_INIT; + sha512_process(&ctx, data, length); + sha512_final(&ctx, out); +} diff --git a/mpy-modules/sha512/sha512.h b/mpy-modules/sha512/sha512.h deleted file mode 120000 index 152f9e7..0000000 --- a/mpy-modules/sha512/sha512.h +++ /dev/null @@ -1 +0,0 @@ -/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/sha512.h \ No newline at end of file diff --git a/mpy-modules/sha512/sha512.h b/mpy-modules/sha512/sha512.h new file mode 100644 index 0000000..5b2e06c --- /dev/null +++ b/mpy-modules/sha512/sha512.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013 Arttu Hynninen + * Licensed under the MIT License. See the LICENSE file for the full text. + */ + +#pragma once +#include + +typedef struct _sha512_ctx { + uint64_t len; + uint64_t state [8]; + uint8_t buflen; + uint8_t buffer [128]; +} sha512_ctx; + +/* + * Macros for static initialization + */ + +#define SHA512_INIT_STATE { \ + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, \ + 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL } + +#define SHA512_INIT_BUFFER { \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + +#define SHA512_INIT { 0, SHA512_INIT_STATE, 0, SHA512_INIT_BUFFER } + +/* + * Initializes the context. + */ +void sha512_init(sha512_ctx *ctx); + +/* + * Processes the input buffer. + */ +void sha512_process(sha512_ctx *ctx, const uint8_t *data, uint32_t length); + +/* + * Finalizes and outputs the calculated hash into the buffer. + */ +void sha512_final(sha512_ctx *ctx, uint8_t out [64]); + +/* + * Digests the input buffer and outputs the calculated hash in one function call. + */ +void sha512_simple(const uint8_t *data, uint32_t length, uint8_t out [64]);