replaced softlinks

master
pmvr 2020-06-04 08:01:20 +02:00
parent 183a52d365
commit 92bd3cab63
10 changed files with 851 additions and 10 deletions

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/Makefile

View File

@ -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

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/arithmetic.c

View File

@ -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];
}

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/arithmetic.h

View File

@ -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

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/ec.c

View File

@ -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);
}
}

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/ec.h

View File

@ -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

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/curve25519/main.c

View File

@ -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
}

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/Makefile

View File

@ -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

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/main.c

View File

@ -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
}

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/sha512.c

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2013 Arttu Hynninen
* Licensed under the MIT License. See the LICENSE file for the full text.
*/
#include <stdint.h>
#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);
}

View File

@ -1 +0,0 @@
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/sha512/sha512.h

View File

@ -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 <stdint.h>
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]);