Loading system/gd/smp/Android.bp +1 −2 Original line number Diff line number Diff line filegroup { name: "BluetoothSmpSources", srcs: [ "ecc/p_256_curvepara.cc", "ecc/p_256_multprecision.cc", "ecc/multprecision.cc", "ecc/p_256_ecc_pp.cc", ] } Loading system/gd/smp/ecc/p_256_multprecision.cc→system/gd/smp/ecc/multprecision.cc +23 −29 Original line number Diff line number Diff line Loading @@ -22,23 +22,26 @@ * ******************************************************************************/ #include "smp/ecc/p_256_multprecision.h" #include "smp/ecc/multprecision.h" #include <string.h> #include "smp/ecc/p_256_ecc_pp.h" namespace bluetooth { namespace smp { namespace ecc { #define DWORD_BITS 32 #define DWORD_BYTES 4 #define DWORD_BITS_SHIFT 5 void multiprecision_init(uint32_t* c) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = 0; } void multiprecision_copy(uint32_t* c, uint32_t* a) { void multiprecision_copy(uint32_t* c, const uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = a[i]; } int multiprecision_compare(uint32_t* a, uint32_t* b) { int multiprecision_compare(const uint32_t* a, const uint32_t* b) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; Loading @@ -46,7 +49,7 @@ int multiprecision_compare(uint32_t* a, uint32_t* b) { return 0; } int multiprecision_iszero(uint32_t* a) { int multiprecision_iszero(const uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) if (a[i]) return 0; Loading Loading @@ -77,7 +80,7 @@ uint32_t multiprecision_most_signbits(uint32_t* a) { return (((aMostSignDWORDs - 1) << DWORD_BITS_SHIFT) + multiprecision_dword_bits(a[aMostSignDWORDs - 1])); } uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t multiprecision_add(uint32_t* c, const uint32_t* a, const uint32_t* b) { uint32_t carrier; uint32_t temp; Loading @@ -94,7 +97,7 @@ uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { } // c=a-b uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t multiprecision_sub(uint32_t* c, const uint32_t* a, const uint32_t* b) { uint32_t borrow; uint32_t temp; Loading @@ -110,11 +113,8 @@ uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { } // c = a << 1 void multiprecision_lshift_mod(uint32_t* c, uint32_t* a) { uint32_t carrier; uint32_t* modp = curve_p256.p; carrier = multiprecision_lshift(c, a); void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, const uint32_t* modp) { uint32_t carrier = multiprecision_lshift(c, a); if (carrier) { multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { Loading @@ -140,24 +140,21 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a) { // Curve specific optimization when p is a pseudo-Mersenns prime, // p=2^(KEY_LENGTH_BITS)-omega void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b) { void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp) { uint32_t cc[2 * KEY_LENGTH_DWORDS_P256]; multiprecision_mult(cc, a, b); multiprecision_fast_mod_P256(c, cc); multiprecision_fast_mod_P256(c, cc, modp); } // Curve specific optimization when p is a pseudo-Mersenns prime void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a) { multiprecision_mersenns_mult_mod(c, a, a); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, const uint32_t* modp) { multiprecision_mersenns_mult_mod(c, a, a, modp); } // c=(a+b) mod p, b<p, a<p void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t* modp = curve_p256.p; carrier = multiprecision_add(c, a, b); void multiprecision_add_mod(uint32_t* c, const uint32_t* a, const uint32_t* b, const uint32_t* modp) { uint32_t carrier = multiprecision_add(c, a, b); if (carrier) { multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { Loading @@ -166,9 +163,8 @@ void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { } // c=(a-b) mod p, a<p, b<p void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b) { void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp) { uint32_t borrow; uint32_t* modp = curve_p256.p; borrow = multiprecision_sub(c, a, b); if (borrow) multiprecision_add(c, c, modp); Loading Loading @@ -220,7 +216,7 @@ void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b) { } } void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a, const uint32_t* modp) { uint32_t A; uint32_t B; uint32_t C; Loading @@ -236,7 +232,6 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { uint8_t UF; uint8_t UG; uint32_t U; uint32_t* modp = curve_p256.p; // C = a[13] + a[14] + a[15]; C = a[13]; Loading Loading @@ -453,11 +448,10 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { if (multiprecision_compare(c, modp) >= 0) multiprecision_sub(c, c, modp); } void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, const uint32_t* modp) { uint32_t v[KEY_LENGTH_DWORDS_P256]; uint32_t A[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t C[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t* modp = curve_p256.p; multiprecision_copy(v, modp); multiprecision_init(A); Loading Loading @@ -492,10 +486,10 @@ void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { if (multiprecision_compare(u, v) >= 0) { multiprecision_sub(u, u, v); multiprecision_sub_mod(A, A, C); multiprecision_sub_mod(A, A, C, modp); } else { multiprecision_sub(v, v, u); multiprecision_sub_mod(C, C, A); multiprecision_sub_mod(C, C, A, modp); } } Loading system/gd/smp/ecc/p_256_multprecision.h→system/gd/smp/ecc/multprecision.h +14 −21 Original line number Diff line number Diff line Loading @@ -29,37 +29,30 @@ namespace bluetooth { namespace smp { namespace ecc { #define DWORD_BITS 32 #define DWORD_BYTES 4 #define DWORD_BITS_SHIFT 5 #define KEY_LENGTH_DWORDS_P256 8 /* Arithmetic Operations*/ int multiprecision_compare(uint32_t* a, uint32_t* b); int multiprecision_iszero(uint32_t* a); int multiprecision_compare(const uint32_t* a, const uint32_t* b); int multiprecision_iszero(const uint32_t* a); void multiprecision_init(uint32_t* c); void multiprecision_copy(uint32_t* c, uint32_t* a); void multiprecision_copy(uint32_t* c, const uint32_t* a); uint32_t multiprecision_dword_bits(uint32_t a); uint32_t multiprecision_most_signdwords(uint32_t* a); uint32_t multiprecision_most_signbits(uint32_t* a); void multiprecision_inv_mod(uint32_t* aminus, uint32_t* a); uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b); // c=a+b void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b); uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b); // c=a-b void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_inv_mod(uint32_t* aminus, uint32_t* a, const uint32_t* modp); uint32_t multiprecision_add(uint32_t* c, const uint32_t* a, const uint32_t* b); // c=a+b void multiprecision_add_mod(uint32_t* c, const uint32_t* a, const uint32_t* b, const uint32_t* modp); uint32_t multiprecision_sub(uint32_t* c, const uint32_t* a, const uint32_t* b); // c=a-b void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp); void multiprecision_rshift(uint32_t* c, uint32_t* a); // c=a>>1, return carrier void multiprecision_lshift_mod(uint32_t* c, uint32_t* a); // c=a<<b, return carrier void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, const uint32_t* modp); // c=a<<b, return carrier uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a); // c=a<<b, return carrier void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b); // c=a*b void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a); void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, const uint32_t* modp); uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a); void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_fast_mod(uint32_t* c, uint32_t* a); void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a); void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a, const uint32_t* modp); } // namespace ecc } // namespace smp Loading system/gd/smp/ecc/p_256_curvepara.ccdeleted 100644 → 0 +0 −82 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2006-2015 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /******************************************************************************* * * This file contains simple pairing algorithms * ******************************************************************************/ #include <string.h> #include "smp/ecc/p_256_ecc_pp.h" namespace bluetooth { namespace smp { namespace ecc { void p_256_init_curve() { elliptic_curve_t* ec = &curve_p256; ec->p[7] = 0xFFFFFFFF; ec->p[6] = 0x00000001; ec->p[5] = 0x0; ec->p[4] = 0x0; ec->p[3] = 0x0; ec->p[2] = 0xFFFFFFFF; ec->p[1] = 0xFFFFFFFF; ec->p[0] = 0xFFFFFFFF; memset(ec->omega, 0, KEY_LENGTH_DWORDS_P256); memset(ec->a, 0, KEY_LENGTH_DWORDS_P256); ec->a_minus3 = true; // b ec->b[7] = 0x5ac635d8; ec->b[6] = 0xaa3a93e7; ec->b[5] = 0xb3ebbd55; ec->b[4] = 0x769886bc; ec->b[3] = 0x651d06b0; ec->b[2] = 0xcc53b0f6; ec->b[1] = 0x3bce3c3e; ec->b[0] = 0x27d2604b; // base point ec->G.x[7] = 0x6b17d1f2; ec->G.x[6] = 0xe12c4247; ec->G.x[5] = 0xf8bce6e5; ec->G.x[4] = 0x63a440f2; ec->G.x[3] = 0x77037d81; ec->G.x[2] = 0x2deb33a0; ec->G.x[1] = 0xf4a13945; ec->G.x[0] = 0xd898c296; ec->G.y[7] = 0x4fe342e2; ec->G.y[6] = 0xfe1a7f9b; ec->G.y[5] = 0x8ee7eb4a; ec->G.y[4] = 0x7c0f9e16; ec->G.y[3] = 0x2bce3357; ec->G.y[2] = 0x6b315ece; ec->G.y[1] = 0xcbb64068; ec->G.y[0] = 0x37bf51f5; } } // namespace ecc } // namespace smp } // namespace bluetooth No newline at end of file system/gd/smp/ecc/p_256_ecc_pp.cc +53 −59 Original line number Diff line number Diff line Loading @@ -26,14 +26,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "smp/ecc/p_256_multprecision.h" #include "smp/ecc/multprecision.h" namespace bluetooth { namespace smp { namespace ecc { elliptic_curve_t curve; elliptic_curve_t curve_p256; const uint32_t* modp = curve_p256.p; static void p_256_init_point(Point* q) { memset(q, 0, sizeof(Point)); Loading Loading @@ -67,29 +66,29 @@ static void ECC_Double(Point* q, Point* p) { y3 = q->y; z3 = q->z; multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2); // t2=t2*t1 multiprecision_lshift_mod(t3, t2); multiprecision_add_mod(t2, t3, t2); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1); // z3=y1*z1 multiprecision_lshift_mod(z3, z3); multiprecision_mersenns_squa_mod(y3, y1); // y3=y1^2 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_mult_mod(t3, y3, x1); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3); multiprecision_mersenns_squa_mod(y3, y3); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_lshift_mod(t1, t3); // t1=2t3 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3); // y3=t1-y3 multiprecision_mersenns_squa_mod(t1, z1, modp); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1, modp); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1, modp); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2, modp); // t2=t2*t1 multiprecision_lshift_mod(t3, t2, modp); multiprecision_add_mod(t2, t3, t2, modp); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1, modp); // z3=y1*z1 multiprecision_lshift_mod(z3, z3, modp); multiprecision_mersenns_squa_mod(y3, y1, modp); // y3=y1^2 multiprecision_lshift_mod(y3, y3, modp); multiprecision_mersenns_mult_mod(t3, y3, x1, modp); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3, modp); multiprecision_mersenns_squa_mod(y3, y3, modp); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3, modp); multiprecision_mersenns_squa_mod(x3, t2, modp); // x3=t2^2 multiprecision_lshift_mod(t1, t3, modp); // t1=2t3 multiprecision_sub_mod(x3, x3, t1, modp); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3, modp); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2, modp); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3, modp); // y3=t1-y3 } // q=q+p, zp must be 1 Loading Loading @@ -128,13 +127,13 @@ static void ECC_Add(Point* r, Point* p, Point* q) { return; } multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2); // t2=t2*y2 multiprecision_mersenns_squa_mod(t1, z1, modp); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1, modp); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1, modp); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2, modp); // t2=t2*y2 multiprecision_sub_mod(t1, t1, x1); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1); // t2=t2-y1 multiprecision_sub_mod(t1, t1, x1, modp); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1, modp); // t2=t2-y1 if (multiprecision_iszero(t1)) { if (multiprecision_iszero(t2)) { Loading @@ -146,18 +145,18 @@ static void ECC_Add(Point* r, Point* p, Point* q) { } } multiprecision_mersenns_mult_mod(z3, z1, t1); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1); // t3=t3*x1 multiprecision_lshift_mod(t1, y3); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1); multiprecision_mersenns_mult_mod(z3, z1, t1, modp); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1, modp); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1, modp); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1, modp); // t3=t3*x1 multiprecision_lshift_mod(t1, y3, modp); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2, modp); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1, modp); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1, modp); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3, modp); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2, modp); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1, modp); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1, modp); } // Computing the Non-Adjacent Form of a positive integer Loading Loading @@ -203,9 +202,6 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { uint32_t NumNaf; Point minus_p; Point r; uint32_t* modp; modp = curve_p256.p; p_256_init_point(&r); multiprecision_init(p->z); Loading Loading @@ -239,30 +235,28 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { } } multiprecision_inv_mod(minus_p.x, q->z); multiprecision_mersenns_squa_mod(q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->x, q->x, q->z); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->y, q->y, q->z); multiprecision_inv_mod(minus_p.x, q->z, modp); multiprecision_mersenns_squa_mod(q->z, minus_p.x, modp); multiprecision_mersenns_mult_mod(q->x, q->x, q->z, modp); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, modp); multiprecision_mersenns_mult_mod(q->y, q->y, q->z, modp); } bool ECC_ValidatePoint(const Point& pt) { p_256_init_curve(); // Ensure y^2 = x^3 + a*x + b (mod p); a = -3 // y^2 mod p uint32_t y2_mod[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y); multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, modp); // Right hand side calculation uint32_t rhs[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x); multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, modp); uint32_t three[KEY_LENGTH_DWORDS_P256] = {0}; three[0] = 3; multiprecision_sub_mod(rhs, rhs, three); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x); multiprecision_add_mod(rhs, rhs, curve_p256.b); multiprecision_sub_mod(rhs, rhs, three, modp); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, modp); multiprecision_add_mod(rhs, rhs, curve_p256.b, modp); return multiprecision_compare(rhs, y2_mod) == 0; } Loading Loading
system/gd/smp/Android.bp +1 −2 Original line number Diff line number Diff line filegroup { name: "BluetoothSmpSources", srcs: [ "ecc/p_256_curvepara.cc", "ecc/p_256_multprecision.cc", "ecc/multprecision.cc", "ecc/p_256_ecc_pp.cc", ] } Loading
system/gd/smp/ecc/p_256_multprecision.cc→system/gd/smp/ecc/multprecision.cc +23 −29 Original line number Diff line number Diff line Loading @@ -22,23 +22,26 @@ * ******************************************************************************/ #include "smp/ecc/p_256_multprecision.h" #include "smp/ecc/multprecision.h" #include <string.h> #include "smp/ecc/p_256_ecc_pp.h" namespace bluetooth { namespace smp { namespace ecc { #define DWORD_BITS 32 #define DWORD_BYTES 4 #define DWORD_BITS_SHIFT 5 void multiprecision_init(uint32_t* c) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = 0; } void multiprecision_copy(uint32_t* c, uint32_t* a) { void multiprecision_copy(uint32_t* c, const uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = a[i]; } int multiprecision_compare(uint32_t* a, uint32_t* b) { int multiprecision_compare(const uint32_t* a, const uint32_t* b) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; Loading @@ -46,7 +49,7 @@ int multiprecision_compare(uint32_t* a, uint32_t* b) { return 0; } int multiprecision_iszero(uint32_t* a) { int multiprecision_iszero(const uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) if (a[i]) return 0; Loading Loading @@ -77,7 +80,7 @@ uint32_t multiprecision_most_signbits(uint32_t* a) { return (((aMostSignDWORDs - 1) << DWORD_BITS_SHIFT) + multiprecision_dword_bits(a[aMostSignDWORDs - 1])); } uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t multiprecision_add(uint32_t* c, const uint32_t* a, const uint32_t* b) { uint32_t carrier; uint32_t temp; Loading @@ -94,7 +97,7 @@ uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { } // c=a-b uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t multiprecision_sub(uint32_t* c, const uint32_t* a, const uint32_t* b) { uint32_t borrow; uint32_t temp; Loading @@ -110,11 +113,8 @@ uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { } // c = a << 1 void multiprecision_lshift_mod(uint32_t* c, uint32_t* a) { uint32_t carrier; uint32_t* modp = curve_p256.p; carrier = multiprecision_lshift(c, a); void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, const uint32_t* modp) { uint32_t carrier = multiprecision_lshift(c, a); if (carrier) { multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { Loading @@ -140,24 +140,21 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a) { // Curve specific optimization when p is a pseudo-Mersenns prime, // p=2^(KEY_LENGTH_BITS)-omega void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b) { void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp) { uint32_t cc[2 * KEY_LENGTH_DWORDS_P256]; multiprecision_mult(cc, a, b); multiprecision_fast_mod_P256(c, cc); multiprecision_fast_mod_P256(c, cc, modp); } // Curve specific optimization when p is a pseudo-Mersenns prime void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a) { multiprecision_mersenns_mult_mod(c, a, a); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, const uint32_t* modp) { multiprecision_mersenns_mult_mod(c, a, a, modp); } // c=(a+b) mod p, b<p, a<p void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t* modp = curve_p256.p; carrier = multiprecision_add(c, a, b); void multiprecision_add_mod(uint32_t* c, const uint32_t* a, const uint32_t* b, const uint32_t* modp) { uint32_t carrier = multiprecision_add(c, a, b); if (carrier) { multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { Loading @@ -166,9 +163,8 @@ void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { } // c=(a-b) mod p, a<p, b<p void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b) { void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp) { uint32_t borrow; uint32_t* modp = curve_p256.p; borrow = multiprecision_sub(c, a, b); if (borrow) multiprecision_add(c, c, modp); Loading Loading @@ -220,7 +216,7 @@ void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b) { } } void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a, const uint32_t* modp) { uint32_t A; uint32_t B; uint32_t C; Loading @@ -236,7 +232,6 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { uint8_t UF; uint8_t UG; uint32_t U; uint32_t* modp = curve_p256.p; // C = a[13] + a[14] + a[15]; C = a[13]; Loading Loading @@ -453,11 +448,10 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { if (multiprecision_compare(c, modp) >= 0) multiprecision_sub(c, c, modp); } void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, const uint32_t* modp) { uint32_t v[KEY_LENGTH_DWORDS_P256]; uint32_t A[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t C[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t* modp = curve_p256.p; multiprecision_copy(v, modp); multiprecision_init(A); Loading Loading @@ -492,10 +486,10 @@ void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { if (multiprecision_compare(u, v) >= 0) { multiprecision_sub(u, u, v); multiprecision_sub_mod(A, A, C); multiprecision_sub_mod(A, A, C, modp); } else { multiprecision_sub(v, v, u); multiprecision_sub_mod(C, C, A); multiprecision_sub_mod(C, C, A, modp); } } Loading
system/gd/smp/ecc/p_256_multprecision.h→system/gd/smp/ecc/multprecision.h +14 −21 Original line number Diff line number Diff line Loading @@ -29,37 +29,30 @@ namespace bluetooth { namespace smp { namespace ecc { #define DWORD_BITS 32 #define DWORD_BYTES 4 #define DWORD_BITS_SHIFT 5 #define KEY_LENGTH_DWORDS_P256 8 /* Arithmetic Operations*/ int multiprecision_compare(uint32_t* a, uint32_t* b); int multiprecision_iszero(uint32_t* a); int multiprecision_compare(const uint32_t* a, const uint32_t* b); int multiprecision_iszero(const uint32_t* a); void multiprecision_init(uint32_t* c); void multiprecision_copy(uint32_t* c, uint32_t* a); void multiprecision_copy(uint32_t* c, const uint32_t* a); uint32_t multiprecision_dword_bits(uint32_t a); uint32_t multiprecision_most_signdwords(uint32_t* a); uint32_t multiprecision_most_signbits(uint32_t* a); void multiprecision_inv_mod(uint32_t* aminus, uint32_t* a); uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b); // c=a+b void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b); uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b); // c=a-b void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_inv_mod(uint32_t* aminus, uint32_t* a, const uint32_t* modp); uint32_t multiprecision_add(uint32_t* c, const uint32_t* a, const uint32_t* b); // c=a+b void multiprecision_add_mod(uint32_t* c, const uint32_t* a, const uint32_t* b, const uint32_t* modp); uint32_t multiprecision_sub(uint32_t* c, const uint32_t* a, const uint32_t* b); // c=a-b void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp); void multiprecision_rshift(uint32_t* c, uint32_t* a); // c=a>>1, return carrier void multiprecision_lshift_mod(uint32_t* c, uint32_t* a); // c=a<<b, return carrier void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, const uint32_t* modp); // c=a<<b, return carrier uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a); // c=a<<b, return carrier void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b); // c=a*b void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a); void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, const uint32_t* modp); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, const uint32_t* modp); uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a); void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b); void multiprecision_fast_mod(uint32_t* c, uint32_t* a); void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a); void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a, const uint32_t* modp); } // namespace ecc } // namespace smp Loading
system/gd/smp/ecc/p_256_curvepara.ccdeleted 100644 → 0 +0 −82 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2006-2015 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ /******************************************************************************* * * This file contains simple pairing algorithms * ******************************************************************************/ #include <string.h> #include "smp/ecc/p_256_ecc_pp.h" namespace bluetooth { namespace smp { namespace ecc { void p_256_init_curve() { elliptic_curve_t* ec = &curve_p256; ec->p[7] = 0xFFFFFFFF; ec->p[6] = 0x00000001; ec->p[5] = 0x0; ec->p[4] = 0x0; ec->p[3] = 0x0; ec->p[2] = 0xFFFFFFFF; ec->p[1] = 0xFFFFFFFF; ec->p[0] = 0xFFFFFFFF; memset(ec->omega, 0, KEY_LENGTH_DWORDS_P256); memset(ec->a, 0, KEY_LENGTH_DWORDS_P256); ec->a_minus3 = true; // b ec->b[7] = 0x5ac635d8; ec->b[6] = 0xaa3a93e7; ec->b[5] = 0xb3ebbd55; ec->b[4] = 0x769886bc; ec->b[3] = 0x651d06b0; ec->b[2] = 0xcc53b0f6; ec->b[1] = 0x3bce3c3e; ec->b[0] = 0x27d2604b; // base point ec->G.x[7] = 0x6b17d1f2; ec->G.x[6] = 0xe12c4247; ec->G.x[5] = 0xf8bce6e5; ec->G.x[4] = 0x63a440f2; ec->G.x[3] = 0x77037d81; ec->G.x[2] = 0x2deb33a0; ec->G.x[1] = 0xf4a13945; ec->G.x[0] = 0xd898c296; ec->G.y[7] = 0x4fe342e2; ec->G.y[6] = 0xfe1a7f9b; ec->G.y[5] = 0x8ee7eb4a; ec->G.y[4] = 0x7c0f9e16; ec->G.y[3] = 0x2bce3357; ec->G.y[2] = 0x6b315ece; ec->G.y[1] = 0xcbb64068; ec->G.y[0] = 0x37bf51f5; } } // namespace ecc } // namespace smp } // namespace bluetooth No newline at end of file
system/gd/smp/ecc/p_256_ecc_pp.cc +53 −59 Original line number Diff line number Diff line Loading @@ -26,14 +26,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "smp/ecc/p_256_multprecision.h" #include "smp/ecc/multprecision.h" namespace bluetooth { namespace smp { namespace ecc { elliptic_curve_t curve; elliptic_curve_t curve_p256; const uint32_t* modp = curve_p256.p; static void p_256_init_point(Point* q) { memset(q, 0, sizeof(Point)); Loading Loading @@ -67,29 +66,29 @@ static void ECC_Double(Point* q, Point* p) { y3 = q->y; z3 = q->z; multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2); // t2=t2*t1 multiprecision_lshift_mod(t3, t2); multiprecision_add_mod(t2, t3, t2); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1); // z3=y1*z1 multiprecision_lshift_mod(z3, z3); multiprecision_mersenns_squa_mod(y3, y1); // y3=y1^2 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_mult_mod(t3, y3, x1); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3); multiprecision_mersenns_squa_mod(y3, y3); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_lshift_mod(t1, t3); // t1=2t3 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3); // y3=t1-y3 multiprecision_mersenns_squa_mod(t1, z1, modp); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1, modp); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1, modp); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2, modp); // t2=t2*t1 multiprecision_lshift_mod(t3, t2, modp); multiprecision_add_mod(t2, t3, t2, modp); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1, modp); // z3=y1*z1 multiprecision_lshift_mod(z3, z3, modp); multiprecision_mersenns_squa_mod(y3, y1, modp); // y3=y1^2 multiprecision_lshift_mod(y3, y3, modp); multiprecision_mersenns_mult_mod(t3, y3, x1, modp); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3, modp); multiprecision_mersenns_squa_mod(y3, y3, modp); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3, modp); multiprecision_mersenns_squa_mod(x3, t2, modp); // x3=t2^2 multiprecision_lshift_mod(t1, t3, modp); // t1=2t3 multiprecision_sub_mod(x3, x3, t1, modp); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3, modp); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2, modp); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3, modp); // y3=t1-y3 } // q=q+p, zp must be 1 Loading Loading @@ -128,13 +127,13 @@ static void ECC_Add(Point* r, Point* p, Point* q) { return; } multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2); // t2=t2*y2 multiprecision_mersenns_squa_mod(t1, z1, modp); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1, modp); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1, modp); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2, modp); // t2=t2*y2 multiprecision_sub_mod(t1, t1, x1); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1); // t2=t2-y1 multiprecision_sub_mod(t1, t1, x1, modp); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1, modp); // t2=t2-y1 if (multiprecision_iszero(t1)) { if (multiprecision_iszero(t2)) { Loading @@ -146,18 +145,18 @@ static void ECC_Add(Point* r, Point* p, Point* q) { } } multiprecision_mersenns_mult_mod(z3, z1, t1); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1); // t3=t3*x1 multiprecision_lshift_mod(t1, y3); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1); multiprecision_mersenns_mult_mod(z3, z1, t1, modp); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1, modp); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1, modp); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1, modp); // t3=t3*x1 multiprecision_lshift_mod(t1, y3, modp); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2, modp); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1, modp); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1, modp); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3, modp); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2, modp); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1, modp); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1, modp); } // Computing the Non-Adjacent Form of a positive integer Loading Loading @@ -203,9 +202,6 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { uint32_t NumNaf; Point minus_p; Point r; uint32_t* modp; modp = curve_p256.p; p_256_init_point(&r); multiprecision_init(p->z); Loading Loading @@ -239,30 +235,28 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { } } multiprecision_inv_mod(minus_p.x, q->z); multiprecision_mersenns_squa_mod(q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->x, q->x, q->z); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->y, q->y, q->z); multiprecision_inv_mod(minus_p.x, q->z, modp); multiprecision_mersenns_squa_mod(q->z, minus_p.x, modp); multiprecision_mersenns_mult_mod(q->x, q->x, q->z, modp); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, modp); multiprecision_mersenns_mult_mod(q->y, q->y, q->z, modp); } bool ECC_ValidatePoint(const Point& pt) { p_256_init_curve(); // Ensure y^2 = x^3 + a*x + b (mod p); a = -3 // y^2 mod p uint32_t y2_mod[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y); multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, modp); // Right hand side calculation uint32_t rhs[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x); multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, modp); uint32_t three[KEY_LENGTH_DWORDS_P256] = {0}; three[0] = 3; multiprecision_sub_mod(rhs, rhs, three); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x); multiprecision_add_mod(rhs, rhs, curve_p256.b); multiprecision_sub_mod(rhs, rhs, three, modp); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, modp); multiprecision_add_mod(rhs, rhs, curve_p256.b, modp); return multiprecision_compare(rhs, y2_mod) == 0; } Loading