|
参考了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] = ∑ 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; } |
微信公众号
手机版