replaced softlinks
parent
183a52d365
commit
92bd3cab63
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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];
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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 <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);
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
/home/mvr/Dokumente/Projekte/micropython/mpy-Module/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 <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]);
|
Loading…
Reference in New Issue