From ecd8ce1882debff101e2ab58745650b5eb05306e Mon Sep 17 00:00:00 2001 From: aidan garske Date: Wed, 3 Jul 2024 08:21:33 -0700 Subject: [PATCH 1/3] ecc_sign_determinisitic.c test for for deterministic ECDSA Prime Field for SECP256R1, SECP384R1, and SECP521R. With SHA256, SHA384, and SHA512 tests. --- pk/ecc/ecc_sign_deterministic | Bin 0 -> 35280 bytes pk/ecc/ecc_sign_deterministic.c | 530 ++++++++++++++++++++++++++++++++ 2 files changed, 530 insertions(+) create mode 100755 pk/ecc/ecc_sign_deterministic create mode 100644 pk/ecc/ecc_sign_deterministic.c diff --git a/pk/ecc/ecc_sign_deterministic b/pk/ecc/ecc_sign_deterministic new file mode 100755 index 0000000000000000000000000000000000000000..0b4c1cfbd93d5ee4d6801c4a5405fde697f59f82 GIT binary patch literal 35280 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 GRsIggzidqa literal 0 HcmV?d00001 diff --git a/pk/ecc/ecc_sign_deterministic.c b/pk/ecc/ecc_sign_deterministic.c new file mode 100644 index 000000000..4a5b14082 --- /dev/null +++ b/pk/ecc/ecc_sign_deterministic.c @@ -0,0 +1,530 @@ +/* ecc_sign_deterministic.c + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Example to demonstrate hashing and ECC Sign deterministic */ +/* +./configure CFLAGS="-DWOLFSSL_PUBLIC_MP" && make && sudo make install +gcc -lwolfssl -o ecc_sign ecc_sign.c +*/ + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef WOLFSSL_PUBLIC_MP + +/* KAT from RFC6979 */ +/* message = "sample": */ +static const char kMsg[] = "sample"; + +/* Choose Hash Algorithm */ +#if 1 + #define DIGEST_SZ WC_SHA256_DIGEST_SIZE + #define HASH_FUNC crypto_sha256 +#elif 0 + #define DIGEST_SZ WC_SHA384_DIGEST_SIZE + #define HASH_FUNC crypto_sha384 +#elif 0 + #define DIGEST_SZ WC_SHA512_DIGEST_SIZE + #define HASH_FUNC crypto_sha512 +#endif + +/* Choose Test Key Curve */ +#if 0 + + /* SECP256R1 */ + #define ECC_KEY_CURVE ECC_SECP256R1 + #define ECC_KEY_SIZE 32 + + /* Test Vector: ECDSA, 256 Bits (Prime Field) */ + static const uint8_t kPrivKey[] = { + /* d */ + 0xC9, 0xAF, 0xA9, 0xD8, 0x45, 0xBA, 0x75, 0x16, + 0x6B, 0x5C, 0x21, 0x57, 0x67, 0xB1, 0xD6, 0x93, + 0x4E, 0x50, 0xC3, 0xDB, 0x36, 0xE8, 0x9B, 0x12, + 0x7B, 0x8A, 0x62, 0x2B, 0x12, 0x0F, 0x67, 0x21 + }; + static const uint8_t kPubKey[] = { + /* Qx */ + 0x60, 0xFE, 0xD4, 0xBA, 0x25, 0x5A, 0x9D, 0x31, + 0xC9, 0x61, 0xEB, 0x74, 0xC6, 0x35, 0x6D, 0x68, + 0xC0, 0x49, 0xB8, 0x92, 0x3B, 0x61, 0xFA, 0x6C, + 0xE6, 0x69, 0x62, 0x2E, 0x60, 0xF2, 0x9F, 0xB6, + /* Qy */ + 0x79, 0x03, 0xFE, 0x10, 0x08, 0xB8, 0xBC, 0x99, + 0xA4, 0x1A, 0xE9, 0xE9, 0x56, 0x28, 0xBC, 0x64, + 0xF2, 0xF1, 0xB2, 0x0C, 0x2D, 0x7E, 0x9F, 0x51, + 0x77, 0xA3, 0xC2, 0x94, 0xD4, 0x46, 0x22, 0x99 + }; + +#elif 0 + + /* SECP384R1 */ + #define ECC_KEY_CURVE ECC_SECP384R1 + #define ECC_KEY_SIZE 48 + + /* Test Vector: ECDSA, 384 Bits (Prime Field) */ + static const uint8_t kPrivKey[] = { + /* d */ + 0x6B, 0x9D, 0x3D, 0xAD, 0x2E, 0x1B, 0x8C, 0x1C, + 0x05, 0xB1, 0x98, 0x75, 0xB6, 0x65, 0x9F, 0x4D, + 0xE2, 0x3C, 0x3B, 0x66, 0x7B, 0xF2, 0x97, 0xBA, + 0x9A, 0xA4, 0x77, 0x40, 0x78, 0x71, 0x37, 0xD8, + 0x96, 0xD5, 0x72, 0x4E, 0x4C, 0x70, 0xA8, 0x25, + 0xF8, 0x72, 0xC9, 0xEA, 0x60, 0xD2, 0xED, 0xF5 + }; + static const uint8_t kPubKey[] = { + /* Qx */ + 0xEC, 0x3A, 0x4E, 0x41, 0x5B, 0x4E, 0x19, 0xA4, + 0x56, 0x86, 0x18, 0x02, 0x9F, 0x42, 0x7F, 0xA5, + 0xDA, 0x9A, 0x8B, 0xC4, 0xAE, 0x92, 0xE0, 0x2E, + 0x06, 0xAA, 0xE5, 0x28, 0x6B, 0x30, 0x0C, 0x64, + 0xDE, 0xF8, 0xF0, 0xEA, 0x90, 0x55, 0x86, 0x60, + 0x64, 0xA2, 0x54, 0x51, 0x54, 0x80, 0xBC, 0x13, + /* Qy */ + 0x80, 0x15, 0xD9, 0xB7, 0x2D, 0x7D, 0x57, 0x24, + 0x4E, 0xA8, 0xEF, 0x9A, 0xC0, 0xC6, 0x21, 0x89, + 0x67, 0x08, 0xA5, 0x93, 0x67, 0xF9, 0xDF, 0xB9, + 0xF5, 0x4C, 0xA8, 0x4B, 0x3F, 0x1C, 0x9D, 0xB1, + 0x28, 0x8B, 0x23, 0x1C, 0x3A, 0xE0, 0xD4, 0xFE, + 0x73, 0x44, 0xFD, 0x25, 0x33, 0x26, 0x47, 0x20 + }; + +#elif 1 + + /* The test for SECP521R1 does not work in this example yet */ + /* SECP521R1 */ + #define ECC_KEY_CURVE ECC_SECP521R1 + #define ECC_KEY_SIZE 66 + + /* Test Vector: ECDSA, 521 Bits (Prime Field) */ + static const uint8_t kPrivKey[] = { + /* d */ + 0x00, 0xFA, 0xD0, 0x6D, 0xAA, 0x62, 0xBA, 0x3B, 0x25, 0xD2, 0xFB, + 0x40, 0x13, 0x3D, 0xA7, 0x57, 0x20, 0x5D, 0xE6, 0x7F, 0x5B, 0xB0, + 0x01, 0x8F, 0xEE, 0x8C, 0x86, 0xE1, 0xB6, 0x8C, 0x7E, 0x75, 0xCA, + 0xA8, 0x96, 0xEB, 0x32, 0xF1, 0xF4, 0x7C, 0x70, 0x85, 0x58, 0x36, + 0xA6, 0xD1, 0x6F, 0xCC, 0x14, 0x66, 0xF6, 0xD8, 0xFB, 0xEC, 0x67, + 0xDB, 0x89, 0xEC, 0x0C, 0x08, 0xB0, 0xE9, 0x96, 0xB8, 0x35, 0x38 + }; + + static const uint8_t kPubKey[] = { + /* Qx */ + 0x01, 0x89, 0x45, 0x50, 0xD0, 0x78, 0x59, 0x32, 0xE0, 0x0E, 0xAA, + 0x23, 0xB6, 0x94, 0xF2, 0x13, 0xF8, 0xC3, 0x12, 0x1F, 0x86, 0xDC, + 0x97, 0xA0, 0x4E, 0x5A, 0x71, 0x67, 0xDB, 0x4E, 0x5B, 0xCD, 0x37, + 0x11, 0x23, 0xD4, 0x6E, 0x45, 0xDB, 0x6B, 0x5D, 0x53, 0x70, 0xA7, + 0xF2, 0x0F, 0xB6, 0x33, 0x15, 0x5D, 0x38, 0xFF, 0xA1, 0x6D, 0x2B, + 0xD7, 0x61, 0xDC, 0xAC, 0x47, 0x4B, 0x9A, 0x2F, 0x50, 0x23, 0xA4, + /* Qy */ + 0x00, 0x49, 0x31, 0x01, 0xC9, 0x62, 0xCD, 0x4D, 0x2F, 0xDD, 0xF7, + 0x82, 0x28, 0x5E, 0x64, 0x58, 0x41, 0x39, 0xC2, 0xF9, 0x1B, 0x47, + 0xF8, 0x7F, 0xF8, 0x23, 0x54, 0xD6, 0x63, 0x0F, 0x74, 0x6A, 0x28, + 0xA0, 0xDB, 0x25, 0x74, 0x1B, 0x5B, 0x34, 0xA8, 0x28, 0x00, 0x8B, + 0x22, 0xAC, 0xC2, 0x3F, 0x92, 0x4F, 0xAA, 0xFB, 0xD4, 0xD3, 0x3F, + 0x81, 0xEA, 0x66, 0x95, 0x6D, 0xFE, 0xAA, 0x2B, 0xFD, 0xFC, 0xF5 + }; +#endif + +#ifndef NO_SHA256 +/* perform hashing block by block */ +int crypto_sha256(const uint8_t *buf, uint32_t len, uint8_t *hash, + uint32_t hashSz, uint32_t blkSz) +{ + int ret; + uint32_t i = 0, chunk; + wc_Sha256 sha; + + /* validate arguments */ + if ((buf == NULL && len > 0) || hash == NULL || + hashSz < WC_SHA256_DIGEST_SIZE || blkSz == 0) + { + return BAD_FUNC_ARG; + } + + /* Init Sha256 structure */ + ret = wc_InitSha256(&sha); + if (ret != 0) { + return ret; + } + while (i < len) { + chunk = blkSz; + if ((chunk + i) > len) + chunk = len - i; + /* Perform chunked update */ + ret = wc_Sha256Update(&sha, (buf + i), chunk); + if (ret != 0) { + break; + } + i += chunk; + } + if (ret == 0) { + /* Get final digest result */ + ret = wc_Sha256Final(&sha, hash); + } + return ret; +} +#endif /* NO_SHA256 */ + +#ifdef WOLFSSL_SHA384 +/* perform hashing block by block */ +int crypto_sha384(const uint8_t *buf, uint32_t len, uint8_t *hash, + uint32_t hashSz, uint32_t blkSz) +{ + int ret; + uint32_t i = 0, chunk; + wc_Sha384 sha; + + /* validate arguments */ + if ((buf == NULL && len > 0) || hash == NULL || + hashSz < WC_SHA384_DIGEST_SIZE || blkSz == 0) + { + return BAD_FUNC_ARG; + } + + /* Init structure */ + ret = wc_InitSha384(&sha); + if (ret != 0) { + return ret; + } + while (i < len) { + chunk = blkSz; + if ((chunk + i) > len) + chunk = len - i; + /* Perform chunked update */ + ret = wc_Sha384Update(&sha, (buf + i), chunk); + if (ret != 0) { + break; + } + i += chunk; + } + if (ret == 0) { + /* Get final digest result */ + ret = wc_Sha384Final(&sha, hash); + } + return ret; +} +#endif /* WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 +/* perform hashing block by block */ +int crypto_sha512(const uint8_t *buf, uint32_t len, uint8_t *hash, + uint32_t hashSz, uint32_t blkSz) +{ + int ret; + uint32_t i = 0, chunk; + wc_Sha512 sha; + + /* validate arguments */ + if ((buf == NULL && len > 0) || hash == NULL || + hashSz < WC_SHA512_DIGEST_SIZE || blkSz == 0) + { + return BAD_FUNC_ARG; + } + + /* Init structure */ + ret = wc_InitSha512(&sha); + if (ret != 0) { + return ret; + } + while (i < len) { + chunk = blkSz; + if ((chunk + i) > len) + chunk = len - i; + /* Perform chunked update */ + ret = wc_Sha512Update(&sha, (buf + i), chunk); + if (ret != 0) { + break; + } + i += chunk; + } + if (ret == 0) { + /* Get final digest result */ + ret = wc_Sha512Final(&sha, hash); + } + return ret; +} +#endif /* WOLFSSL_SHA512 */ + +#ifdef HAVE_ECC +#ifdef HAVE_ECC_VERIFY +/* perform verify of signature and hash using public key */ +/* key is public Qx + public Qy */ +/* sig is r + s */ +int crypto_ecc_verify(const uint8_t *key, uint32_t keySz, + const uint8_t *hash, uint32_t hashSz, const uint8_t *sig, uint32_t sigSz, + int curveSz, int curveId) +{ + int ret, verify_res = 0; + mp_int r, s; + ecc_key ecc; + + /* validate arguments */ + if (key == NULL || hash == NULL || sig == NULL || curveSz == 0 || + hashSz == 0 || keySz < (curveSz*2) || sigSz < (curveSz*2)) + { + return BAD_FUNC_ARG; + } + + /* Setup the ECC key */ + ret = wc_ecc_init(&ecc); + if (ret < 0) { + return ret; + } + + /* Setup the signature r/s variables */ + ret = mp_init(&r); + if (ret != MP_OKAY) { + wc_ecc_free(&ecc); + return ret; + } + ret = mp_init(&s); + if (ret != MP_OKAY) { + mp_clear(&r); + wc_ecc_free(&ecc); + return ret; + } + + /* Import public key x/y */ + ret = wc_ecc_import_unsigned( + &ecc, + (byte*)key, /* Public "x" Coordinate */ + (byte*)(key + curveSz), /* Public "y" Coordinate */ + NULL, /* Private "d" (optional) */ + curveId /* ECC Curve Id */ + ); + /* Make sure it was a public key imported */ + if (ret == 0 && ecc.type != ECC_PUBLICKEY) { + ret = ECC_BAD_ARG_E; + } + + /* Import signature r/s */ + if (ret == 0) { + ret = mp_read_unsigned_bin(&r, sig, curveSz); + } + if (ret == 0) { + ret = mp_read_unsigned_bin(&s, sig + curveSz, curveSz); + } + + /* Verify ECC Signature */ + if (ret == 0) { + ret = wc_ecc_verify_hash_ex( + &r, &s, /* r/s as mp_int */ + hash, hashSz, /* computed hash digest */ + &verify_res, /* verification result 1=success */ + &ecc + ); + } + + /* check verify result */ + if (ret == 0 && verify_res == 0) { + ret = SIG_VERIFY_E; + } + + mp_clear(&r); + mp_clear(&s); + wc_ecc_free(&ecc); + + return ret; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_SIGN +/* perform signature operation against hash using private key */ +int crypto_ecc_sign(const uint8_t *key, uint32_t keySz, + const uint8_t *hash, uint32_t hashSz, uint8_t *sig, uint32_t* sigSz, + int curveSz, int curveId) +{ + int ret; + mp_int r, s; + word32 rSz, sSz; + ecc_key ecc; + WC_RNG rng; + + /* validate arguments */ + if (key == NULL || hash == NULL || sig == NULL || sigSz == NULL || + curveSz == 0 || hashSz == 0 || keySz < curveSz || *sigSz < (curveSz*2)) + { + return BAD_FUNC_ARG; + } + + /* Initialize signature result */ + memset(sig, 0, curveSz*2); + + /* Setup the RNG */ + ret = wc_InitRng(&rng); + if (ret < 0) { + return ret; + } + + /* Setup the ECC key */ + ret = wc_ecc_init(&ecc); + if (ret < 0) { + wc_FreeRng(&rng); + return ret; + } + + /* enable deterministic signing */ + /* result will always be the same, no random point is used */ + wc_ecc_set_deterministic(&ecc, 1); + + /* Setup the signature r/s variables */ + ret = mp_init(&r); + if (ret != MP_OKAY) { + wc_ecc_free(&ecc); + wc_FreeRng(&rng); + return ret; + } + ret = mp_init(&s); + if (ret != MP_OKAY) { + mp_clear(&r); + wc_ecc_free(&ecc); + wc_FreeRng(&rng); + return ret; + } + + /* Import private key "k" */ + ret = wc_ecc_import_private_key_ex( + key, keySz, /* private key "d" */ + NULL, 0, /* public (optional) */ + &ecc, + curveId /* ECC Curve Id */ + ); + if (ret == 0) { + /* Verify ECC Signature */ + ret = wc_ecc_sign_hash_ex( + hash, hashSz, /* computed hash digest */ + &rng, &ecc, /* random and key context */ + &r, &s /* r/s as mp_int */ + ); + + /* export sign r/s - zero pad to key size */ + rSz = mp_unsigned_bin_size(&r); + mp_to_unsigned_bin(&r, &sig[curveSz - rSz]); + sSz = mp_unsigned_bin_size(&s); + mp_to_unsigned_bin(&s, &sig[curveSz + (curveSz - sSz)]); + } + + mp_clear(&r); + mp_clear(&s); + wc_ecc_free(&ecc); + wc_FreeRng(&rng); + + return ret; +} +#endif /* HAVE_ECC_SIGN */ +#endif /* HAVE_ECC */ + +static void print_hex(uint8_t* data, int sz) +{ + int i; + for (i = 0; i < sz; i++) { + printf("%02X ", data[i]); + if (i > 0 && ((i+1) % 16) == 0) + printf("\n"); + } + printf("\n"); +} + +#endif /* WOLFSSL_PUBLIC_MP */ + +int main() +{ +#if defined(HAVE_ECC) && defined(HAVE_ECC_SIGN) && defined(HAVE_ECC_VERIFY) && \ + defined(WOLFSSL_PUBLIC_MP) && \ + (!defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)) + int ret; + uint8_t hash[DIGEST_SZ]; + uint8_t sig[ECC_KEY_SIZE*2]; + uint32_t sigSz = 0; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + +if (ECC_KEY_SIZE == 66) + printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8)-7, DIGEST_SZ*8); +else + printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8), DIGEST_SZ*8); + + memset(sig, 0, sizeof(sig)); + + ret = HASH_FUNC( + (uint8_t*)kMsg, strlen(kMsg), /* string without null termination */ + hash, sizeof(hash), /* hash digest result */ + 32 /* configurable block / chunk size */ + ); + if (ret == 0) { + printf("Digest %d\n", (int)sizeof(hash)); + print_hex(hash, sizeof(hash)); + + /* Sign hash using private key */ + /* Note: result of an ECC sign varies for each call even with same + private key and hash. This is because a new random public key is + used for each operation. */ + sigSz = sizeof(sig); + ret = crypto_ecc_sign( + kPrivKey, sizeof(kPrivKey), /* private key */ + hash, sizeof(hash), /* computed hash digest */ + sig, &sigSz, /* signature r/s */ + ECC_KEY_SIZE, /* SECP256R1 curve size in bytes */ + ECC_KEY_CURVE /* curve id */ + ); + } + + if (ret == 0) { + /* Verify generated signature is valid */ + ret = crypto_ecc_verify( + kPubKey, sizeof(kPubKey), /* public key point x/y */ + hash, sizeof(hash), /* computed hash digest */ + sig, sigSz, /* signature r/s */ + ECC_KEY_SIZE, /* curve size in bytes */ + ECC_KEY_CURVE /* curve id */ + ); + } + + if (ret == 0) { + printf("Signature %d\n", sigSz); + print_hex(sig, sigSz); + + printf("Success\n"); + } + else { + printf("Failure %d: %s\n", ret, wc_GetErrorString(ret)); + ret = -1; + } + + return ret; +#else + printf("wolfSSL requires ECC, SHA2 and WOLFSSL_PUBLIC_MP\n"); + return -1; +#endif +} \ No newline at end of file From 49bfb703a7fdc59ef20c7a8f746b8a73887a70c0 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Wed, 3 Jul 2024 09:58:38 -0700 Subject: [PATCH 2/3] ecc_sign_determinisitic.c test for for deterministic ECDSA Prime Field for SECP256R1, SECP384R1, and SECP521R. With SHA256, SHA384, and SHA512 tests. --- pk/ecc/ecc_sign_deterministic | Bin 35280 -> 35280 bytes pk/ecc/ecc_sign_deterministic.c | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pk/ecc/ecc_sign_deterministic b/pk/ecc/ecc_sign_deterministic index 0b4c1cfbd93d5ee4d6801c4a5405fde697f59f82..3893ba21919fcb32dbef56777dc0b06a7ae00a81 100755 GIT binary patch delta 1661 zcmZ8ie@s(X6u$4Zg+`P@bqHu?`85g-HfSwvwWTW0ltc_HnVSYhbbt(942}_^6$mAx zs|~ozHrX`P&3`sSK#7DAHB}jf%$OHL%;wC(lKptFC7Z-B!U)~D=RLA!H+kQ^=bZ0+ z=iJ-(ZbizAl?jLddQ-02tzhpNjQ*r|cY)eMIl1g`6|-f#N=)xF67VuJ{F4 zu}nUtc$uxHch#HdUz{OvNQt_Y=+JN)KgcD}9p@i?I%OZZ_)Xg{bsK%3&>5AL3k|2J zWAmw~9-@ZAc+Ns!DeUH-uc4vB3tS6*&9slpq*qLte19Abo6@;A-i^?i zJ8;|hTO=Yqg@9j}^a;zePB;~C2mc0lRWv_C<`4Y?0T%>TbAz1mdq8= zw{4qB&&W|M{Y=I7Fy7%Ahdn4g8CaS#N@5O3eqo&L#~QVtoAjYAIpt#rLi3okAg{6R z=QLu=<|kFuXg4KXg8-BP9#+kz4fc$9BD3*qmUw!}o?Y-Qk77s~kk=T#BCoLs7gc0{ zKDTGI2H9EqHG5dge&Y5Ci(%nB_()jrvPpV^>5lJV8e{LN@9_|ka?t7NDOebDG17XO zWCVGs0M@<Qj(#3^H#3yuhc)EzL^8h&AtpUdk;NM{k(0znQ zZl)sO?xMM^Yd%o5T1*mrrQ(d%7eG zxcp6RZr?o+_!A5emp$KN+2A`nnU~paRG4=aS3r5aRre;rAQW!s78!I)FQ4yT#Fcw zn1HB9+<=&bn2eZe!D%z%i--oqbi_==mk^DJxri^*1J3tbrv|_LP8e%SYN$+mqwe}+ zy085H4;JY&{h1GrZq@7R(vGZ5k7XUaTrgGr`@0j{P96`Hj()hkdg;Wk^+)rM%=eG9 zs8$lRqqq95rq0gpH{N<{{@IPSdFT2on!mW$JH02p5B5to!^1}O3@s42b>j$oJ=n9} zNq;Oh4)d<0-8sQVLip45b?=b;_i7sJYg@=}6`45+&YEM#s)*_I@oI8VMZ_AqvtvVL zupYj|Py>Tz5Mo2D5miAx$cNNHO$c6pFO-XiR@xl$E#1v*_}o@+?T-|@T)C(F75fyu u-m#^^V3V`5L0JbXGZxvlEB5NYN2y{5VLxo&Zz^_Zn{3yu+QVtyLCwFnToE<^ delta 1816 zcmZ8i4NOy46u$4ZAO@v?n2DHJEsRbbLTRBbmcpc?I{eG#Wc=t<1VmvB9qJ+!D8+S! z`E!*m#Kg{-Nr(wuP=hQoK{Dzxv$`2|Lo!$vS3nkKCcDpxa?luh-XJ(T1RptXpeimoBqv#L?-$)Uw3;(6^oZVH zMK80Zv`ZR6$2fV&Wuu@mi_yz%%lK96{qq zQ3Y|2=+CO-ygHDU#-HS_QC_`~%cEP=k^H84^pJWv*F~GuW!zahU$cYDqQx2=zj!Wf z*3|Mf0W?UnoqsiemT0uRe*kqSEC=aG!f9?Ftx8n9`JF!@c9Yv$;U==$7oaP1!*%6v zKA(5V96}r>x7{>7lngrpZs#*_pPS8B2z=KR1gan~qaC1=i7#`VG+Jxm!~AK!Hi{di z_1ZYz=uf}WD#LAl&l4UI)>!k$Q@Ry=q#s?SyD-02iX6gvxk3AN3T~Kk`bFF!x>z5v z?n@zxmE&M-H}zO6dSC>xB{`E-&PuTY)(%q-8%H~9oTs!>zbO2k1Z$xvVV39@+NzJ{ z1ElnUK0bH^NKgi5#HvL!B1sXHA}Dcd^b(qp6de~RxR5l;KOb~ZSYwe?frG=1(hErn z%NW~Ahu=7>?jUBnX`{~@1)nJ7FXUd6dD%5t8*?S>|kH3i+JA_lBWPKZoH!w zMBa3C8FGN?-2-d;*XD+;9&>|XJ$O>v<-kd^cX{i_eLlO*q6MY(Izu9}6+#S%1EA_; zJSadgTZIR0uNkTeU9nOuZ$^WS6$jNcQ@sN2YfPHa(7>ASl}0jGZ(3wPFuc75)2!y0StztBXUkp1cI7-Kc z3A4^Ev&k?u2CIA6ap&IjI^iV?+-kN{tKp<26FTulWg+Gu<|7s&79s9OEI}+qEJHkq zSdMrY@qNUjh?R&{h&70{h;@h`AbyyDuX@Cf5KkbULOhMwi1-O&6XIEVEBTm({N*Wb z+0~I0_5D=J0>i~^^4v$3Y!`R@_xifQtM!%debd}HqWa^{qouaYgwOB1^KDrE_=Bm( z1%39%^8#E$jqMt?@w0xM-L%bT~=_d;&ZiX(cd-$<)W7fL`eH*iHCx$5Q zmYDkX<-T5e@rmr}*7$|FTHmL|EAQ`ocq#q0rq!Dj7s$Fe?$)l`8&>x}t5I&x%S_dE zPe!CqSSA#2+}kZXSfq6JMIDUDRyQk&WBH|S@6rEG39&8_U0cUYbC@5cLBd=_wF4e{y^bQ zk|iO|Jeq0^%NZ*m5^|!5LAf}lGtVP&@=pGS)ah3xC4`+w5PVm`;%#%B+2EhKP|k?< zfOx^26YW^~g>~tcQrJKclW2Hku!v0%Y`tjDTx{z^dn{gvXNq>PMz9NJ?6zgKt$zOk Divo!R diff --git a/pk/ecc/ecc_sign_deterministic.c b/pk/ecc/ecc_sign_deterministic.c index 4a5b14082..d564c44d7 100644 --- a/pk/ecc/ecc_sign_deterministic.c +++ b/pk/ecc/ecc_sign_deterministic.c @@ -58,7 +58,7 @@ static const char kMsg[] = "sample"; #endif /* Choose Test Key Curve */ -#if 0 +#if 1 /* SECP256R1 */ #define ECC_KEY_CURVE ECC_SECP256R1 @@ -118,7 +118,7 @@ static const char kMsg[] = "sample"; 0x73, 0x44, 0xFD, 0x25, 0x33, 0x26, 0x47, 0x20 }; -#elif 1 +#elif 0 /* The test for SECP521R1 does not work in this example yet */ /* SECP521R1 */ From 413b997e7fabf5870aee2fff8da1ed7409d5edc9 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Wed, 3 Jul 2024 10:25:58 -0700 Subject: [PATCH 3/3] ecc_sign_determinisitic.c test for for deterministic ECDSA Prime Field for SECP256R1, SECP384R1, and SECP521R .gitignore addition and binary file exclusion. --- .gitignore | 1 + pk/ecc/ecc_sign_deterministic | Bin 35280 -> 0 bytes pk/ecc/ecc_sign_deterministic.c | 17 +++++++---------- 3 files changed, 8 insertions(+), 10 deletions(-) delete mode 100755 pk/ecc/ecc_sign_deterministic diff --git a/.gitignore b/.gitignore index e18ad5de9..0447f2992 100644 --- a/.gitignore +++ b/.gitignore @@ -224,6 +224,7 @@ pk/rsa-pss/sign.txt pk/rsa/rsa-nb pk/ecc/ecc_verify pk/ecc/ecc_sign +pk/ecc/ecc_sign_determinisitc pk/ecc/ecc_pub pk/ecc/ecc_keys diff --git a/pk/ecc/ecc_sign_deterministic b/pk/ecc/ecc_sign_deterministic deleted file mode 100755 index 3893ba21919fcb32dbef56777dc0b06a7ae00a81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35280 zcmeHQeQ;FO6~CK+B7W=^6%jvJksuHahOeTC4VZ_InqW$Zr~`d&Hk)K8$tJTOLbPiG zn^j()TNy1DS{>4l>9kcx>r5yz;si)dm@@5-lQPuuM>oO&hY+p7}CTxB(#CakO!-$8r#;GMQx4-Nn zOa@)6FPHtqV>;v4B+)U>kiS?wQ5zc*x&2MMSNc0(YvlR7!4%uyCAPpYg0Xls9BCNi zC(ien?XTJHC*FC{8aOZbYmLOlC+v=|>`OAfHrt5!3G;P2L)$PCkuBj!oe_@Iw=zF5 zzBg=twB~dX?~Y0K$dcA|H^?x`S8Z5j-1p$RYPq^)GOqkOx@*ceB3dgS$S@jO$7lID z{y14+P$uos;*0Q~Ww)ss&)bT%>mJa`*UG2_t^S0315a1>GFek!eh88*fd$1!b~ymC z*yeNFS;W}PK=;;^5XGqHJtM@Ap-1Ug1)_`Ag9!H-%l)W7>zenp5Pnce6pesNN z6S3&R=5X!8y7uNe@O0e(qBvf-=h^qZbM)?gyMNK~LBnOSg80I< ztjuvQM>B6i-%fDRy*zH!iM5&1inhapb$_9 zCy)5Kssx1QY@a0fm4hapb$_9Cz#zl%VPZhoL|8_r?|x;1$j{@`7=gl=kQb@Sk3qobo{ z_a>COxvPqpOa;nvGp(cQOP8Ufnd>Q572Y(=Md~0~2=6oa(|GD4L*eb5$z5dc_imSZ z1nJ(`o%1ln!43ZGnejk&%4$xvd@RqesM^&-)87K_C=a< z43j+$H9(M$J6nPMX%_z1ST=%VJfY)$i(;h*`38TQALj z^O4*(Y{>9lzSCY$KY?f_N6f^qZq^K%l_$$h?L?nO%2<@-2yn;9B9$D*O3_9T2nPZ0 zH7q=Nr+2&TJ^@AA%h0Et=hb=+LqzxRFHehP!hb%PZifGvt z+ORjZk^4@V+A&KzRw#u}!x#p`#ab3}-AasDT9(kRIhOZ7)9IfBsT{-`utu?n_+3biMdn(^vli4V|`jLfVcChvqCm0i&n{I7R_a7rjkCiXah_t zc@nMJXkqECO5dU1dyvrE`KCs8!*~9NS!zS z2A$`yx5?C`PAA=#$O<+-i4IF+{d=W;*C)_7ocgy)eRfoaj=XKxxNQO1B42f@W<(DH z8_(f#pk!;7_LzrqPdQws`Ih1cJl;;kk9(>AAx>RPB0Zf3v=UjX#s?2P?f}*@KY{d3 zcE216w+E?l+^;#+_+e|+3|f^ZZ8v(Ro75^YT5m-r!vKsrEeP{evKJxPG2I{^OB{j* z&HOlb$u@h~gSLcF-c^(-n~&7jmw0D&!k-ZI{Mk>t$#Q?d7Ov09p9-_GUp|OBYhY(T ze!eW5lsL4j3sPXziA`m84lUpo<&YmOS>j=vdpPoUddBu`hB=Vs_j~>jH zp3(abVY;Kaa*8r@P*8Gpplxcs42qpxy_8(tGFkkj^HZmeom_1EMRZsi>!-){-$7I4 zo|JdCJKNavy;6yteF!Dn*>dTOSG?P4yO1VrXUvP}K%4!Xk!|+#{c%4d zj8SsLN(`440olaSydsVAF)Sc9 z{Ss1+(^>NsGh_DPp`O>FEsSWh`8jNhGt;}r^|5xv8R9+tc_UW*B^2`xUXyK>e^0h~ z0<<3&IuvY
8(M=2XOAMwuWz`Qs=@x9Z9CSI&-2y^+p)2BU4{e4;|Rk`=s`O4p- zIzV3}=J7W~Zaxc>J4??TC?ln-rP4eMo-0M$#6)YddS>NxNLKClL#G^1gWYHF5u)u# zC3oOvdjvvgyb1MpNC9r&<0VdJna|AxhbYQeuO^H8cPI1*p#K)>S7a(X&0qCRnnO%q z`J5?q_vX^)9YfIVLV=Je*18ks-85Voj@&YctVD-y9)^RzfPsTk(CE{4(EUb=>93&y@Q=dD#a}ht zxvjSgHu$P}1(o-5*YibB4buzhteH67r%_&G{E-#fX>Vo|+ISG0)q|BI-hE4^AciMp z3=#D3XU{i_q<*T$^Og_IJ)itFbq?!7pB7MGFV*ScGXx^f&@{D?q1_a9W@V{VxS7;b zy}r#yMvHO~jTU{#?j z%WJrt&gBd)XL5NXmp60i=W;febGV$#d!uSKU!mcYC$I z3YEV+6c0sP!jW(+9uE4e!wnJthEOa%Rg{MtQ2UGOrV5e<;)!TTa*1Ft6pKw2YXaeB zDZJZX1it9bMGyN0eM`zK7HDZ}4&^x^j=uhr6WW2q^rlU>Y;5@1@fX%r9r@j|+;^uv z`HkA*Y2Jog9=kAbpy<(;OOFOViod(GrLkx2{^wT&&NcrrTwC(kslEH!3orPl?0Fy&dBq)1?fuG@9~}PHz?#{60Jyl(9?n@~`hxbl)4f7;wY{&L+PHbK z|JH;3vt-TJSVOYD4k_?;kRR-{?I0Vf@j&5vvR>fO)!0sUM$gT;tQ0Yl)1ngT7^` zpFVu3re8=@Q(96@Ka!}Xl%<;9-c-|17^>+DnCffn`dYiD&kK^%tBPv8ueruEk!$){ zMsnH@O|`_x*Fm2h#8aMAJ&SA6AuClX1QY@a0fm4hapb$_9Cy)5Kssx1QY@a0fm4hapb$_9C6q16M(Dy2+2lO830%)#B6yR_QPc7&PP#0)F z=r{=H+jww1gl7?G11Ju95ws6<0(1&gQYbuM1#Jbr3OWv&glG+1!N#Uoyve8wMDbtU zlcXio5(~viPFyS=2sRO8)Z=uAiIRpyAX+DE17Wm9!;yHsFk)>+usIZnatjAZ#JLd- z1?r4MB!;6SLUl$hjRnPc>%}ssk`W6(5rSqs+8lz#mY}gF8VaqCG;sU=P+W^fTcg!+ z3@t@#F`v*)!mziV_eRVA|i4@OI7DQvSUn* zkTx0vu|}uQ$3xL@eY-=9|A4-_y22XnPyhP3SEFtYV^2bVZT3G@K}r{>6QTVz325icl<$H3r0^g(8ciKMH9vYG?_X z2>3P_hjHdcPZJee=*Ga64P^_v3c3nEaK#_`{N?Q208A63iI?8yEkPiyw9I*Gl8D zcyE&Yn7{ch{vH>vyZDVRzTU+rTs)nbCI2BXTrax#AG!FSyZAmAf5OFo;NlB0Qz??; z-QeQstQ=?mY8SuJ#YbE`o##SlxzIT-bao469-Y}T4MbQqW}N^ diff --git a/pk/ecc/ecc_sign_deterministic.c b/pk/ecc/ecc_sign_deterministic.c index d564c44d7..c85366f92 100644 --- a/pk/ecc/ecc_sign_deterministic.c +++ b/pk/ecc/ecc_sign_deterministic.c @@ -466,14 +466,14 @@ int main() uint8_t sig[ECC_KEY_SIZE*2]; uint32_t sigSz = 0; -#ifdef DEBUG_WOLFSSL - wolfSSL_Debugging_ON(); -#endif + #ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); + #endif -if (ECC_KEY_SIZE == 66) - printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8)-7, DIGEST_SZ*8); -else - printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8), DIGEST_SZ*8); + if (ECC_KEY_SIZE == 66) + printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8)-7, DIGEST_SZ*8); + else + printf("Running NIST P-%d,SHA-%d Deterministic Sign Test\n", (ECC_KEY_SIZE*8), DIGEST_SZ*8); memset(sig, 0, sizeof(sig)); @@ -487,9 +487,6 @@ else print_hex(hash, sizeof(hash)); /* Sign hash using private key */ - /* Note: result of an ECC sign varies for each call even with same - private key and hash. This is because a new random public key is - used for each operation. */ sigSz = sizeof(sig); ret = crypto_ecc_sign( kPrivKey, sizeof(kPrivKey), /* private key */