mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 22:51:41 +01:00 
			
		
		
		
	
		
			
	
	
		
			169 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			169 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /* mbedTLS bignum (MPI) self-tests as unit tests
 | ||
|  | */ | ||
|  | #include <string.h>
 | ||
|  | #include <stdio.h>
 | ||
|  | #include <stdbool.h>
 | ||
|  | #include <esp_system.h>
 | ||
|  | #include "mbedtls/bignum.h"
 | ||
|  | #include "freertos/FreeRTOS.h"
 | ||
|  | #include "freertos/task.h"
 | ||
|  | #include "freertos/semphr.h"
 | ||
|  | #include "unity.h"
 | ||
|  | #include "sdkconfig.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /* Debugging function to print an MPI number to stdout. Happens to
 | ||
|  |    print output that can be copy-pasted directly into a Python shell. | ||
|  | */ | ||
|  | void mbedtls_mpi_printf(const char *name, const mbedtls_mpi *X) | ||
|  | { | ||
|  |     static char buf[1024]; | ||
|  |     size_t n; | ||
|  |     memset(buf, 0, sizeof(buf)); | ||
|  |     mbedtls_mpi_write_string(X, 16, buf, sizeof(buf)-1, &n); | ||
|  |     if(n) { | ||
|  |         printf("%s = 0x%s\n", name, buf); | ||
|  |     } else { | ||
|  |         printf("%s = TOOLONG\n", name); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | /* Assert E = A * B */ | ||
|  | static void test_bignum_mult(const char *a_str, const char *b_str, const char *e_str, size_t mod_bits) | ||
|  | { | ||
|  |     mbedtls_mpi A, B, X, E, M; | ||
|  |     char x_buf[1024] = { 0 }; | ||
|  |     size_t x_buf_len = 0; | ||
|  | 
 | ||
|  |     mbedtls_mpi_init(&A); | ||
|  |     mbedtls_mpi_init(&B); | ||
|  |     mbedtls_mpi_init(&X); | ||
|  |     mbedtls_mpi_init(&E); | ||
|  | 
 | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&A, 16, a_str)); | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&B, 16, b_str)); | ||
|  | 
 | ||
|  |     /* E = A * B */ | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&E, 16, e_str)); | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_mul_mpi(&X, &A, &B)); | ||
|  | 
 | ||
|  |     mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len); | ||
|  |     TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "mbedtls_mpi_mul_mpi result wrong"); | ||
|  | 
 | ||
|  |     /* if mod_bits arg is set, also do a esp_mpi_mul_mod() call */ | ||
|  |     if (mod_bits > 0) { | ||
|  |         mbedtls_mpi_init(&M); | ||
|  |         for(int i = 0; i < mod_bits; i++) { | ||
|  |             mbedtls_mpi_set_bit(&M, i, 1); | ||
|  |         } | ||
|  | 
 | ||
|  |         TEST_ASSERT_FALSE(esp_mpi_mul_mpi_mod(&X, &A, &B, &M)); | ||
|  | 
 | ||
|  |         mbedtls_mpi_write_string(&X, 16, x_buf, sizeof(x_buf)-1, &x_buf_len); | ||
|  |         TEST_ASSERT_EQUAL_STRING_MESSAGE(e_str, x_buf, "esp_mpi_mul_mpi_mod result wrong"); | ||
|  | 
 | ||
|  |         mbedtls_mpi_free(&M); | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  |     mbedtls_mpi_free(&A); | ||
|  |     mbedtls_mpi_free(&B); | ||
|  |     mbedtls_mpi_free(&X); | ||
|  |     mbedtls_mpi_free(&E); | ||
|  | } | ||
|  | 
 | ||
|  | TEST_CASE("test MPI multiplication", "[bignum]") | ||
|  | { | ||
|  |     /* Run some trivial numbers tests w/ various high modulo bit counts,
 | ||
|  |      should make no difference to the result | ||
|  |     */ | ||
|  |     for(int i = 512; i <= 4096; i+= 512) { | ||
|  |         test_bignum_mult("10", "100", "1000", | ||
|  |                          i); | ||
|  |     } | ||
|  | 
 | ||
|  |     test_bignum_mult("60006FA8D3E3BD746BE39B860FFAADB4F108E15CF2ED8F685FB0E86CC4CB107A488720B41C3F1E18550F00619CD3CA8442296ECB54D2F52ECEE5346D310195700000000", | ||
|  |                      "BF474CA7", | ||
|  |                      "047BB102CAF58A48D3D97E4231BC0B753051D8232B9B939A2A4E310F88E65FEFD7762FC2DE0E2BAD6AA51A391DFFABD120653A312E4998F42E2C03AA404EE63B67275BC100000000", | ||
|  |                      1024); | ||
|  | 
 | ||
|  |     test_bignum_mult("49493AC229831EC01EEB01EAF3BBEBC44768EADF9ABC30C87D1791F5E04245756ED4965361EC0599626884DF079B6B5738985CE76BD66FAA67E3AAAD60775D5C9D44C09FDF9E27C033696C007BE1C540D718CA148BA01FFA4A358541E9E9F02F72BE37AFAB037DAEA5E3669A770400D2F4A5DBBD83A83919D05E3DD64787BC80000000", | ||
|  |                      "B878CC29", | ||
|  |                      "34CF37013066D5BDA2C86CF1FE7BDA66604E0D55DAFF9864B6E727BFF5871012B0AB73D28D4E100BA1E4607AA2A247C912FDBC435C6BF7C5F8E00278AE1381B1E5F6E3D52D2CBE819F0D65CB37370666D156E7A7B1FD4698D8C9D3165FC8A83F9293C839521993619CCF8180E521300C4306206C9121D629754F1FCC7839BF6DFAF33080000000", | ||
|  |                      3072); | ||
|  | 
 | ||
|  |     test_bignum_mult("24BF6185468786FDD303083D25E64EFC66CA472BC44D253102F8B4A9D3BFA75091386C0077937FE33FA3252D28855837AE1B484A8A9A45F7EE8C0C634F9E8CDDF79C5CE07EE72C7F123142198164234CABB724CF78B8173B9F880FC86322407AF1FEDFDDE2BEB674CA15F3E81A1521E071513A1E85B5DFA031F21ECAE9A34D", | ||
|  |                      "010001", | ||
|  |                      "24BF8644A80CCD855A00DB402E2374E2B5C6ADF60B78E97E2829B7A288697B103888FD38E393F776BF8664D04DB280BD0652F665D2E4D0923483FAEF5C01DC7C847A547CDBC7AB663EB0544AC37DA4B0CF03D0869D878FF3B6C3AF5072EAA39D3279D1DCC29C9933808ABDFE0DFD3BF59331AB6FBFD46556119250BD086E36A34D", | ||
|  |         1536); | ||
|  | 
 | ||
|  |     test_bignum_mult("-5D88B669C417EDD02213723546A906B7E9DA7683780E9B54856A2147467ADA316F8819D69486FC8056FE1E8EA7DEC5D5EF12340B95C4FC966F4B348D35893620", | ||
|  |                      "9AE7FBC99546432DF71896FC239EADAEF38D18D2B2F0E2DD275AA977E2BF4411F5A3B2A5D33605AEBBCCBA7FEB9F2D2FA74206CEC169D74BF5A8C50D6F48EA08", | ||
|  |                      "-38990016EB21810E3B5E6AEE339AEE72BB7CD629C4C9270A3D832701A2949BC82B2BE5A7F900C0C9937464699862821976095187D646884E8FBF01DE8C3442F3BC97B670AF573EFB74A9BBEBE4432EE74B0A83BBCDF59485D332B1FF49EB461A3A8B12C38FD72C7772D75EC6EBA5633199540C47678BD2F4ADEEA40830C2F100", | ||
|  |         2048); | ||
|  | 
 | ||
|  | 
 | ||
|  |     /* 1 << 2050 * 0X1234 */ | ||
|  |     test_bignum_mult("400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", | ||
|  |                      "1234", | ||
|  |                      "48D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", | ||
|  |                      3072); | ||
|  | 
 | ||
|  |     /* multiply a 1178 bit number by a 2050 bit number */ | ||
|  |     test_bignum_mult("AAAAAAAAAA75124938ABBECD0EEEEE333333333333333333333FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAABBBBBBBBBBBBBBBBBBBB000000000000000000000000000000000004988A5293848932948872398400000000000FFFFFFFFFFF0000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238", | ||
|  |                      "390587293875124938ABBECD0EEEEE3333333333333333333333333333333399999888000AAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBB00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000EDFABC0204048975876873487387478327482374871327482347328742837483247283748234723874238478327400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003012111111111111111100000000000000000000000111111111111111111111111", | ||
|  |                      "02603AF70D0421C1AD82CE623F28F70B128118D06D00C27D433EC25BA86E6105C3890A0B1973B8BE068CA68E159A21078785DDB37F94216FBF4AEC939958AF4B8CEA2A48895CECA87562FC846EAAE0C866AF9D41EEABFB1D579F5828E9666A15E2AF946F16A189B5C645872FDCA247D309AB0BCAFB0D112881186FCFFEDC87061B4AE4A375E9BBCF579A7BC87A8EAC8C6F66E107986FC603F920F5E1A0FD8C619D88D90066FFFC8F4DB77437EBD7E3BD7E398C4C01F93426E347E039DCA7B0A73C0C90A9C4271BB761ADFF88971D190CE5DA98EFC5D7390D33BC034908AF81D784A4D7F32D0902E0C5DABC706635D5A28FC0E3A364EDEB21E8E117041D0E4B51CA6F9684F434057E7FCF2AF6BD050334B1D11E043B0967154E57354B681161D3C618974D5A7E0385755B80B931AE9B59DD4402BAEC206F04B8440741B3C4CA6D9F7DAF0AE6B3BF1B24B76C2F12B9E9A7C50D32E2093608FC9A30CBD852329E64A9AE0BC3F513899EBFA28629C1DF38081FB8C6630408F70D7B9A37701ABA4176C8B7DCB8CC78BD7783B861A7FC50862E75191DB8", | ||
|  |                      4096); | ||
|  | } | ||
|  | 
 | ||
|  | static void test_bignum_modexp(const char *z_str, const char *x_str, const char *y_str, const char *m_str) | ||
|  | { | ||
|  |     mbedtls_mpi Z, X, Y, M; | ||
|  |     char z_buf[400] = { 0 }; | ||
|  |     size_t z_buf_len = 0; | ||
|  | 
 | ||
|  |     mbedtls_mpi_init(&Z); | ||
|  |     mbedtls_mpi_init(&X); | ||
|  |     mbedtls_mpi_init(&Y); | ||
|  |     mbedtls_mpi_init(&M); | ||
|  | 
 | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&X, 16, x_str)); | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&Y, 16, y_str)); | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_read_string(&M, 16, m_str)); | ||
|  | 
 | ||
|  |     //mbedtls_mpi_printf("X", &X);
 | ||
|  |     //mbedtls_mpi_printf("X", &Y);
 | ||
|  |     //mbedtls_mpi_printf("M", &M);
 | ||
|  | 
 | ||
|  |     /* Z = (X ^ Y) mod M */ | ||
|  |     TEST_ASSERT_FALSE(mbedtls_mpi_exp_mod(&Z, &X, &Y, &M, NULL)); | ||
|  | 
 | ||
|  |     mbedtls_mpi_write_string(&Z, 16, z_buf, sizeof(z_buf)-1, &z_buf_len); | ||
|  |     TEST_ASSERT_EQUAL_STRING_MESSAGE(z_str, z_buf, "mbedtls_mpi_exp_mod incorrect"); | ||
|  | } | ||
|  | 
 | ||
|  | TEST_CASE("test MPI modexp", "[bignum]") | ||
|  | { | ||
|  |     test_bignum_modexp("01000000", "1000", "2", "FFFFFFFF"); | ||
|  |     test_bignum_modexp("014B5A90", "1234", "2", "FFFFFFF"); | ||
|  |     test_bignum_modexp("01234321", "1111", "2", "FFFFFFFF"); | ||
|  |     test_bignum_modexp("02", "5", "1", "3"); | ||
|  |     test_bignum_modexp("22", "55", "1", "33"); | ||
|  |     test_bignum_modexp("0222", "555", "1", "333"); | ||
|  |     test_bignum_modexp("2222", "5555", "1", "3333"); | ||
|  |     test_bignum_modexp("11", "5555", "1", "33"); | ||
|  | 
 | ||
|  |     test_bignum_modexp("55", "1111", "1", "77"); | ||
|  |     test_bignum_modexp("88", "1111", "2", "BB"); | ||
|  | 
 | ||
|  |     test_bignum_modexp("01000000", "2", "128", | ||
|  |                        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); | ||
|  | 
 | ||
|  |     /* failures below here... */ | ||
|  |     test_bignum_modexp("0ABCDEF12345", "ABCDEF12345", "1", "FFFFFFFFFFFF"); | ||
|  |     test_bignum_modexp("0ABCDE", "ABCDE", "1", "FFFFF"); | ||
|  | 
 | ||
|  |     test_bignum_modexp("04", "2", "2", "9"); | ||
|  | } | ||
|  | 
 |