你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

新手接触嵌入式,感谢各路神仙热情帮助,分享一个EC算法

[复制链接]
lvfeng123 发布时间:2019-5-6 07:04
参考了micro-ecc部分代码。内联汇编尚未写完。
代码在STM32L496上验证通过,计算时间是23毫秒。
只支持secp256k1曲线.  
(友情提供上sha256 MD算法);

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define EC_BYTES 32
#if __STDC_VERSION__ >= 199901L
    #define RESTRICT restrict
#else
    #define RESTRICT
#endif
typedef uint32_t ec_word_t;
typedef uint64_t ec_dword_t;
typedef unsigned wordcount_t;

#define HIGH_BIT_SET 0x80000000
#define ec_WORD_BITS 32
#define ec_WORD_BITS_SHIFT 5
#define ec_WORD_BITS_MASK 0x01F
#define ec_WORDS 8
#define ec_N_WORDS 8

#define vli_modSub_fast(result, left, right) vli_modSub((result), (left), (right), curve_p)
#define vli_modSquare_fast(result, left) vli_modMult_fast((result), (left), (left))
#define EVEN(vli) (!(vli[0] & 1))

typedef struct EccPoint {
    ec_word_t x[ec_WORDS];
    ec_word_t y[ec_WORDS];
} EccPoint;
static const ec_word_t curve_p[ec_WORDS] = {0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
//static const ec_word_t curve_b[ec_WORDS] = {0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};
static const EccPoint curve_G = {{0x16F81798, 0x59F2815B, 0x2DCE28D9, 0x029BFCDB, 0xCE870B07, 0x55A06295, 0xF9DCBBAC, 0x79BE667E}, \
                                                                                                                                {0xFB10D4B8, 0x9C47D08F, 0xA6855419, 0xFD17B448, 0x0E1108A8, 0x5DA4FBFC, 0x26A3C465, 0x483ADA77}};
static const ec_word_t curve_n[ec_N_WORDS] = {0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};

static void vli_rshift1(ec_word_t *vli);
static void vli2_rshift1(ec_word_t *vli);
static void vli_set(ec_word_t *dest, const ec_word_t *src);
static void vli_clear(ec_word_t *vli);
static void vli_bytesToNative(uint32_t *native, const uint8_t *bytes);
static void vli_modMult_n(ec_word_t *result, const ec_word_t *left, const ec_word_t *right);
static void vli_mult(ec_word_t *result, const ec_word_t *left, const ec_word_t *right);
static void vli_modSub(ec_word_t *result, const ec_word_t *left, const ec_word_t *right, const ec_word_t *mod);
static void vli_modMult_fast(ec_word_t *result, const ec_word_t *left, const ec_word_t *right);
static void vli_modInv(ec_word_t *result, const ec_word_t *input, const ec_word_t *mod);
static void vli_modAdd(ec_word_t *result, const ec_word_t *left, const ec_word_t *right, const ec_word_t *mod);
static void vli_mmod_fast(ec_word_t *RESTRICT result, ec_word_t *RESTRICT product);
static int vli_equal(const ec_word_t *left, const ec_word_t *right);
static ec_word_t vli_testBit(const ec_word_t *vli, int bit);
static int vli_cmp(const ec_word_t *left, const ec_word_t *right);
static ec_word_t vli_isZero(const ec_word_t *vli);
static ec_word_t vli_sub(ec_word_t *result, const ec_word_t *left, const ec_word_t *right);
static wordcount_t vli_numDigits(const ec_word_t *vli, wordcount_t max_words);
static int vli_numBits(const ec_word_t *vli, wordcount_t max_words);
static int smax(int a, int b);
static void apply_z(ec_word_t * RESTRICT X1, ec_word_t * RESTRICT Y1, const ec_word_t * RESTRICT Z);
static void omega_mult(uint32_t * RESTRICT result, const uint32_t * RESTRICT right);
static void muladd(ec_word_t a, ec_word_t b, ec_word_t *r0, ec_word_t *r1, ec_word_t *r2);
static void XYcZ_add(ec_word_t * RESTRICT X1, ec_word_t * RESTRICT Y1, ec_word_t * RESTRICT X2, ec_word_t * RESTRICT Y2);
static void EccPoint_double_jacobian(ec_word_t * RESTRICT X1, ec_word_t * RESTRICT Y1, ec_word_t * RESTRICT Z1);

int ec_verify(const uint8_t public_key[64], const uint8_t hash[32], const uint8_t signature[64]) {
    ec_word_t u1[ec_N_WORDS], u2[ec_N_WORDS];
    ec_word_t z[ec_N_WORDS];
    EccPoint public, sum;
    ec_word_t rx[ec_WORDS];
    ec_word_t ry[ec_WORDS];
    ec_word_t tx[ec_WORDS];
    ec_word_t ty[ec_WORDS];
    ec_word_t tz[ec_WORDS];
    const EccPoint *points[4];
    const EccPoint *point;
    int numBits;
    int i;
    ec_word_t r[ec_N_WORDS], s[ec_N_WORDS];
    r[ec_N_WORDS - 1] = 0;
    s[ec_N_WORDS - 1] = 0;

    vli_bytesToNative(public.x, public_key);
    vli_bytesToNative(public.y, public_key + EC_BYTES);
    vli_bytesToNative(r, signature);
    vli_bytesToNative(s, signature + EC_BYTES);

    if (vli_isZero(r) || vli_isZero(s)) { /* r, s must not be 0. */
        return 0;
    }
        vli_modInv(z, s, curve_n);
    u1[ec_N_WORDS - 1] = 0;
    vli_bytesToNative(u1, hash);
    vli_modMult_n(u1, u1, z); /* u1 = e/s */
    vli_modMult_n(u2, r, z); /* u2 = r/s */

    /* Calculate sum = G + Q. */
    vli_set(sum.x, public.x);
    vli_set(sum.y, public.y);
    vli_set(tx, curve_G.x);
    vli_set(ty, curve_G.y);
    vli_modSub_fast(z, sum.x, tx); /* Z = x2 - x1 */
    XYcZ_add(tx, ty, sum.x, sum.y);
    vli_modInv(z, z, curve_p); /* Z = 1/Z */
    apply_z(sum.x, sum.y, z);

    /* Use Shamir's trick to calculate u1*G + u2*Q */
    points[0] = 0;
    points[1] = &curve_G;
    points[2] = &public;
    points[3] = &sum;
    numBits = smax(vli_numBits(u1, ec_N_WORDS), vli_numBits(u2, ec_N_WORDS));

    point = points[(!!vli_testBit(u1, numBits - 1)) | ((!!vli_testBit(u2, numBits - 1)) << 1)];
    vli_set(rx, point->x);
    vli_set(ry, point->y);
    vli_clear(z);
    z[0] = 1;

    for (i = numBits - 2; i >= 0; --i) {
        ec_word_t index;
        EccPoint_double_jacobian(rx, ry, z);

        index = (!!vli_testBit(u1, i)) | ((!!vli_testBit(u2, i)) << 1);
        point = points[index];
        if (point) {
            vli_set(tx, point->x);
            vli_set(ty, point->y);
            apply_z(tx, ty, z);
            vli_modSub_fast(tz, rx, tx); /* Z = x2 - x1 */
            XYcZ_add(tx, ty, rx, ry);
            vli_modMult_fast(z, z, tz);
        }
    }
    vli_modInv(z, z, curve_p); /* Z = 1/Z */
    apply_z(rx, ry, z);
    return vli_equal(rx, r);
}
static int vli_equal(const ec_word_t *left, const ec_word_t *right) {
    ec_word_t result = 0;
    int i;
    for (i = ec_WORDS - 1; i >= 0; --i) {
        result |= (left[i] ^ right[i]);
    }
    return (result == 0);
}
static ec_word_t vli_add(ec_word_t *result, const ec_word_t *left, const ec_word_t *right) {
    ec_word_t carry = 0;
    wordcount_t i;
    for (i = 0; i < ec_WORDS; ++i) {
        ec_word_t sum = left[i] + right[i] + carry;
        if (sum != left[i]) {
            carry = (sum < left[i]);
        }
        result[i] = sum;
    }
    return carry;
}

static void vli_bytesToNative(uint32_t *native, const uint8_t *bytes) {
    unsigned i;
    for (i = 0; i < ec_WORDS; ++i) {
        const uint8_t *digit = bytes + 4 * (ec_WORDS - 1 - i);
        native[i] = ((uint32_t)digit[0] << 24) | ((uint32_t)digit[1] << 16) |
                    ((uint32_t)digit[2] << 8) | (uint32_t)digit[3];
    }
}
static ec_word_t vli_isZero(const ec_word_t *vli) {
    wordcount_t i;
    for (i = 0; i < ec_WORDS; ++i) {
        if (vli[i]) {
            return 0;
        }
    }
    return 1;
}
static ec_word_t vli_sub(ec_word_t *result, const ec_word_t *left, const ec_word_t *right) {
    ec_word_t borrow = 0;
    wordcount_t i;
    for (i = 0; i < ec_WORDS; ++i) {
        ec_word_t diff = left[i] - right[i] - borrow;
        if (diff != left[i]) {
            borrow = (diff > left[i]);
        }
        result[i] = diff;
    }
    return borrow;
}

static ec_word_t vli2_sub(ec_word_t *result,
                            const ec_word_t *left,
                            const ec_word_t *right) {
    ec_word_t borrow = 0;
    wordcount_t i;
    for (i = 0; i < ec_WORDS * 2; ++i) {
        ec_word_t diff = left[i] - right[i] - borrow;
        if (diff != left[i]) {
            borrow = (diff > left[i]);
        }
        result[i] = diff;
    }
    return borrow;
}

/* Computes result = (left * right) % curve_n. */
static void vli_modMult_n(ec_word_t *result, const ec_word_t *left, const ec_word_t *right) {
    ec_word_t product[2 * ec_WORDS];
    ec_word_t modMultiple[2 * ec_WORDS];
    ec_word_t tmp[2 * ec_WORDS];
    ec_word_t *v[2] = {tmp, product};
    int i;
    ec_word_t index = 1;

    vli_mult(product, left, right);
    vli_set(modMultiple + ec_WORDS, curve_n); /* works if curve_n has its highest bit set */
    vli_clear(modMultiple);

    for (i = 0; i <= EC_BYTES * 8; ++i) {
        ec_word_t borrow = vli2_sub(v[1 - index], v[index], modMultiple);
        index = !(index ^ borrow); /* Swap the index if there was no borrow */
        vli2_rshift1(modMultiple);
    }
    vli_set(result, v[index]);
}

static void vli_mult(ec_word_t *result, const ec_word_t *left, const ec_word_t *right) {
    ec_word_t r0 = 0;
    ec_word_t r1 = 0;
    ec_word_t r2 = 0;
    wordcount_t i, k;

    /* Compute each digit of result in sequence, maintaining the carries. */
    for (k = 0; k < ec_WORDS; ++k) {
        for (i = 0; i <= k; ++i) {
            muladd(left[i], right[k - i], &r0, &r1, &r2);
        }
        result[k] = r0;
        r0 = r1;
        r1 = r2;
        r2 = 0;
    }
    for (k = ec_WORDS; k < ec_WORDS * 2 - 1; ++k) {
        for (i = (k + 1) - ec_WORDS; i < ec_WORDS; ++i) {
            muladd(left[i], right[k - i], &r0, &r1, &r2);
        }
        result[k] = r0;
        r0 = r1;
        r1 = r2;
        r2 = 0;
    }
    result[ec_WORDS * 2 - 1] = r0;
}

static void muladd(ec_word_t a, ec_word_t b, ec_word_t *r0, ec_word_t *r1, ec_word_t *r2) {
    ec_dword_t p = (ec_dword_t)a * b;
    ec_dword_t r01 = ((ec_dword_t)(*r1) << ec_WORD_BITS) | *r0;
    r01 += p;
    *r2 += (r01 < p);
    *r1 = r01 >> ec_WORD_BITS;
    *r0 = (ec_word_t)r01;
}
//#define muladd_exists 1

static void vli_rshift1(ec_word_t *vli) {
    ec_word_t *end = vli;
    ec_word_t carry = 0;

    vli += ec_WORDS;
    while (vli-- > end) {
        ec_word_t temp = *vli;
        *vli = (temp >> 1) | carry;
        carry = temp << (ec_WORD_BITS - 1);
    }
}

static void vli2_rshift1(ec_word_t *vli) {
    vli_rshift1(vli);
    vli[ec_WORDS - 1] |= vli[ec_WORDS] << (ec_WORD_BITS - 1);
    vli_rshift1(vli + ec_WORDS);
}

static void vli_modSub(ec_word_t *result, const ec_word_t *left, const ec_word_t *right, const ec_word_t *mod) {
    ec_word_t l_borrow = vli_sub(result, left, right);
    if (l_borrow) {
        /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x,
           we can get the correct result from result + mod (with overflow). */
        vli_add(result, result, mod);
    }
}
static void vli_set(ec_word_t *dest, const ec_word_t *src) {
    wordcount_t i;
    for (i = 0; i < ec_WORDS; ++i) {
        dest[i] = src[i];
    }
}

static void XYcZ_add(ec_word_t * RESTRICT X1,
                     ec_word_t * RESTRICT Y1,
                     ec_word_t * RESTRICT X2,
                     ec_word_t * RESTRICT Y2) {
    /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
    ec_word_t t5[ec_WORDS];

    vli_modSub_fast(t5, X2, X1);  /* t5 = x2 - x1 */
    vli_modSquare_fast(t5, t5);   /* t5 = (x2 - x1)^2 = A */
    vli_modMult_fast(X1, X1, t5); /* t1 = x1*A = B */
    vli_modMult_fast(X2, X2, t5); /* t3 = x2*A = C */
    vli_modSub_fast(Y2, Y2, Y1);  /* t4 = y2 - y1 */
    vli_modSquare_fast(t5, Y2);   /* t5 = (y2 - y1)^2 = D */

    vli_modSub_fast(t5, t5, X1);  /* t5 = D - B */
    vli_modSub_fast(t5, t5, X2);  /* t5 = D - B - C = x3 */
    vli_modSub_fast(X2, X2, X1);  /* t3 = C - B */
    vli_modMult_fast(Y1, Y1, X2); /* t2 = y1*(C - B) */
    vli_modSub_fast(X2, X1, t5);  /* t3 = B - x3 */
    vli_modMult_fast(Y2, Y2, X2); /* t4 = (y2 - y1)*(B - x3) */
    vli_modSub_fast(Y2, Y2, Y1);  /* t4 = y3 */

    vli_set(X2, t5);
}

static void EccPoint_double_jacobian(ec_word_t * RESTRICT X1,
                                     ec_word_t * RESTRICT Y1,
                                     ec_word_t * RESTRICT Z1) {
    /* t1 = X, t2 = Y, t3 = Z */
    ec_word_t t4[ec_WORDS];
    ec_word_t t5[ec_WORDS];

    if (vli_isZero(Z1)) {
        return;
    }

    vli_modSquare_fast(t5, Y1);   /* t5 = y1^2 */
    vli_modMult_fast(t4, X1, t5); /* t4 = x1*y1^2 = A */
    vli_modSquare_fast(X1, X1);   /* t1 = x1^2 */
    vli_modSquare_fast(t5, t5);   /* t5 = y1^4 */
    vli_modMult_fast(Z1, Y1, Z1); /* t3 = y1*z1 = z3 */

    vli_modAdd(Y1, X1, X1, curve_p); /* t2 = 2*x1^2 */
    vli_modAdd(Y1, Y1, X1, curve_p); /* t2 = 3*x1^2 */
    if (vli_testBit(Y1, 0)) {
        ec_word_t carry = vli_add(Y1, Y1, curve_p);
        vli_rshift1(Y1);
        Y1[ec_WORDS - 1] |= carry << (ec_WORD_BITS - 1);
    } else {
        vli_rshift1(Y1);
    }
    /* t2 = 3/2*(x1^2) = B */

    vli_modSquare_fast(X1, Y1);      /* t1 = B^2 */
    vli_modSub(X1, X1, t4, curve_p); /* t1 = B^2 - A */
    vli_modSub(X1, X1, t4, curve_p); /* t1 = B^2 - 2A = x3 */

    vli_modSub(t4, t4, X1, curve_p); /* t4 = A - x3 */
    vli_modMult_fast(Y1, Y1, t4);    /* t2 = B * (A - x3) */
    vli_modSub(Y1, Y1, t5, curve_p); /* t2 = B * (A - x3) - y1^4 = y3 */
}
static void vli_modMult_fast(ec_word_t *result,
                             const ec_word_t *left,
                             const ec_word_t *right) {
    ec_word_t product[2 * ec_WORDS];
    vli_mult(product, left, right);
    vli_mmod_fast(result, product);
}
static void vli_modInv(ec_word_t *result, const ec_word_t *input, const ec_word_t *mod) {
    ec_word_t a[ec_WORDS], b[ec_WORDS], u[ec_WORDS], v[ec_WORDS];
    ec_word_t carry;
    int cmpResult;

    if (vli_isZero(input)) {
        vli_clear(result);
        return;
    }

    vli_set(a, input);
    vli_set(b, mod);
    vli_clear(u);
    u[0] = 1;
    vli_clear(v);
    while ((cmpResult = vli_cmp(a, b)) != 0) {
        carry = 0;
        if (EVEN(a)) {
            vli_rshift1(a);
            if (!EVEN(u)) {
                carry = vli_add(u, u, mod);
            }
            vli_rshift1(u);
            if (carry) {
                u[ec_WORDS - 1] |= HIGH_BIT_SET;
            }
        } else if (EVEN(b)) {
            vli_rshift1(b);
            if (!EVEN(v)) {
                carry = vli_add(v, v, mod);
            }
            vli_rshift1(v);
            if (carry) {
                v[ec_WORDS - 1] |= HIGH_BIT_SET;
            }
        } else if (cmpResult > 0) {
            vli_sub(a, a, b);
            vli_rshift1(a);
            if (vli_cmp(u, v) < 0) {
                vli_add(u, u, mod);
            }
            vli_sub(u, u, v);
            if (!EVEN(u)) {
                carry = vli_add(u, u, mod);
            }
            vli_rshift1(u);
            if (carry) {
                u[ec_WORDS - 1] |= HIGH_BIT_SET;
            }
        } else {
            vli_sub(b, b, a);
            vli_rshift1(b);
            if (vli_cmp(v, u) < 0) {
                vli_add(v, v, mod);
            }
            vli_sub(v, v, u);
            if (!EVEN(v)) {
                carry = vli_add(v, v, mod);
            }
            vli_rshift1(v);
            if (carry) {
                v[ec_WORDS - 1] |= HIGH_BIT_SET;
            }
        }
    }
    vli_set(result, u);
}

static void apply_z(ec_word_t * RESTRICT X1,
                    ec_word_t * RESTRICT Y1,
                    const ec_word_t * RESTRICT Z) {
    ec_word_t t1[ec_WORDS];

    vli_modSquare_fast(t1, Z);    /* z^2 */
    vli_modMult_fast(X1, X1, t1); /* x1 * z^2 */
    vli_modMult_fast(t1, t1, Z);  /* z^3 */
    vli_modMult_fast(Y1, Y1, t1); /* y1 * z^3 */
}

static int vli_numBits(const ec_word_t *vli, wordcount_t max_words) {
    ec_word_t i;
    ec_word_t digit;

    wordcount_t num_digits = vli_numDigits(vli, max_words);
    if (num_digits == 0) {
        return 0;
    }

    digit = vli[num_digits - 1];
    for (i = 0; digit; ++i) {
        digit >>= 1;
    }

    return (((int)(num_digits - 1) << ec_WORD_BITS_SHIFT) + i);
}

static wordcount_t vli_numDigits(const ec_word_t *vli, wordcount_t max_words) {
    int i;
    /* Search from the end until we find a non-zero digit.
       We do it in reverse because we expect that most digits will be nonzero. */
    for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) {
    }

    return (i + 1);
}

static ec_word_t vli_testBit(const ec_word_t *vli, int bit) {
    return (vli[bit >> ec_WORD_BITS_SHIFT] & ((ec_word_t)1 << (bit & ec_WORD_BITS_MASK)));
}

static void vli_clear(ec_word_t *vli) {
    wordcount_t i;
    for (i = 0; i < ec_WORDS; ++i) {
        vli[i] = 0;
    }
}

static int smax(int a, int b) {
    return (a > b ? a : b);
}

static int vli_cmp(const ec_word_t *left, const ec_word_t *right) {
    int i;
    for (i = ec_WORDS - 1; i >= 0; --i) {
        if (left[i] > right[i]) {
            return 1;
        } else if (left[i] < right[i]) {
            return -1;
        }
    }
    return 0;
}
static void vli_modAdd(ec_word_t *result, const ec_word_t *left, const ec_word_t *right, const ec_word_t *mod) {
    ec_word_t carry = vli_add(result, left, right);
    if (carry || vli_cmp(result, mod) >= 0)
        vli_sub(result, result, mod);
}

static void vli_mmod_fast(ec_word_t *RESTRICT result, ec_word_t *RESTRICT product) {
    ec_word_t tmp[2 * ec_WORDS];
    ec_word_t carry;

    vli_clear(tmp);
    vli_clear(tmp + ec_WORDS);

    omega_mult(tmp, product + ec_WORDS); /* (Rq, q) = q * c */

    carry = vli_add(result, product, tmp); /* (C, r) = r + q       */
    vli_clear(product);
    omega_mult(product, tmp + ec_WORDS); /* Rq*c */
    carry += vli_add(result, result, product); /* (C1, r) = r + Rq*c */

    while (carry > 0) {
        --carry;
        vli_sub(result, result, curve_p);
    }
    if (vli_cmp(result, curve_p) > 0) {
        vli_sub(result, result, curve_p);
    }
}

static void omega_mult(uint32_t * RESTRICT result, const uint32_t * RESTRICT right) {
    /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */
    uint32_t carry = 0;
    wordcount_t k;

    for (k = 0; k < ec_WORDS; ++k) {
        uint64_t p = (uint64_t)0x3D1 * right[k] + carry;
        result[k] = (p & 0xffffffff);
        carry = p >> 32;
    }
    result[ec_WORDS] = carry;

    result[1 + ec_WORDS] = vli_add(result + 1, result + 1, right); /* add the 2^32 multiple */
}


/*************************************************************************/
/*以下是sha256 算法 c语言实现*/
/************************************************************************/
#define SHFR(x, n) (((x) >> (n)))
#define ROTR(x, n) (((x) >> (n)) | ((x) << ((sizeof(x) << 3) - (n))))
#define ROTL(x, n) (((x) << (n)) | ((x) >> ((sizeof(x) << 3) - (n))))

#define CHX(x, y, z) (((x) &  (y)) ^ (~(x) & (z)))
#define MAJ(x, y, z) (((x) &  (y)) ^ ( (x) & (z)) ^ ((y) & (z)))

#define BSIG0(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define BSIG1(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SSIG0(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
#define SSIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))

static uint32_t k[64] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

int dig(const uint8_t *msg, uint32_t *h){
    uint32_t w[64];
    uint32_t a0, b1, c2, d3, e4, f5, g6, h7;
    uint32_t t1, t2;
    int i = 0;
    int j = 0;
    for (i=0; i<16; i++) {
        w[i] = msg[j]<<24 | msg[j+1]<<16 | msg[j+2]<<8 | msg[j+3];
        j += 4;
    }
    for(i=16; i<64; i++)
        w[i] = SSIG1(w[i-2])+w[i-7]+SSIG0(w[i-15])+w[i-16];
    a0 = h[0];
    b1 = h[1];
    c2 = h[2];
    d3 = h[3];
    e4 = h[4];
    f5 = h[5];
    g6 = h[6];
    h7 = h[7];

    for (i= 0; i<64; i++) {
        t1 = h7 + BSIG1(e4) + CHX(e4, f5, g6) + k[i] + w[i];
        t2 = BSIG0(a0) + MAJ(a0, b1, c2);
        h7 = g6;
        g6 = f5;
        f5 = e4;
        e4 = d3 + t1;
        d3 = c2;
        c2 = b1;
        b1 = a0;
        a0 = t1 + t2;
    }

    h[0] += a0;
    h[1] += b1;
    h[2] += c2;
    h[3] += d3;
    h[4] += e4;
    h[5] += f5;
    h[6] += g6;
    h[7] += h7;

    return 0;
}
void tobe(uint8_t *lehash,uint8_t *out,uint8_t len){
        int i =0,j=0;
        for(i=0;i<len;i++)
                for(j=0;j<4;j++)
                        out[i*4+j] = lehash[(i+1)*4-j-1];

}

int sha256(const uint8_t *src, uint32_t len, uint8_t *hash){
        uint32_t h[8] = {0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19};
    uint32_t i;
    uint32_t bitlen = len * 8;
    uint32_t n = len % 64 < 56 ? len / 64 + 1 : len / 64 + 2;
    uint32_t new_len = 64 * n;
    uint8_t  tmp[new_len];
          //bzero(tmp, new_len);
                memset(tmp,0,new_len);
    memcpy(tmp, src, len);
    tmp[len] = 0x80;
    tobe((uint8_t *)&bitlen,&tmp[new_len-4],1);

    for (i=0; i<n; i++)
        dig(&tmp[i*64], h);
           tobe((uint8_t *)h,hash,8);
    return 0;
}
收藏 1 评论0 发布时间:2019-5-6 07:04

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版