aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2025-01-20 15:55:13 +0000
committerMichael Brown <mcb30@ipxe.org>2025-01-20 16:00:44 +0000
commitcc38d7dd3e379f3f93bcc97390137bbfd4049d60 (patch)
tree16b62e9ae4cb6f5c9f962cb92bab4f1d7a7e0a36
parentd88eb0a1935942cdeccd3efee38f9765d2f1c235 (diff)
downloadipxe-cc38d7dd3e379f3f93bcc97390137bbfd4049d60.tar.gz
[crypto] Add bigint_ntoa() for transcribing big integers
In debug messages, big integers are currently printed as hex dumps. This is quite verbose and cumbersome to check against external sources. Add bigint_ntoa() to transcribe big integers into a static buffer (following the model of inet_ntoa(), eth_ntoa(), uuid_ntoa(), etc). Abbreviate big integers that will not fit within the static buffer, showing both the most significant and least significant digits in the transcription. This is generally the most useful form when visually comparing against external sources (such as test vectors, or results produced by high-level languages). Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/crypto/bigint.c47
-rw-r--r--src/include/ipxe/bigint.h13
2 files changed, 60 insertions, 0 deletions
diff --git a/src/crypto/bigint.c b/src/crypto/bigint.c
index e5e6e2f12..dd75cd9d1 100644
--- a/src/crypto/bigint.c
+++ b/src/crypto/bigint.c
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
#include <assert.h>
+#include <stdio.h>
#include <ipxe/profile.h>
#include <ipxe/bigint.h>
@@ -38,6 +39,52 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
static struct profiler bigint_mod_profiler __profiler =
{ .name = "bigint_mod" };
+/** Minimum number of least significant bytes included in transcription */
+#define BIGINT_NTOA_LSB_MIN 16
+
+/**
+ * Transcribe big integer (for debugging)
+ *
+ * @v value0 Element 0 of big integer to be transcribed
+ * @v size Number of elements
+ * @ret string Big integer in string form (may be abbreviated)
+ */
+const char * bigint_ntoa_raw ( const bigint_element_t *value0,
+ unsigned int size ) {
+ const bigint_t ( size ) __attribute__ (( may_alias ))
+ *value = ( ( const void * ) value0 );
+ bigint_element_t element;
+ static char buf[256];
+ unsigned int count;
+ int threshold;
+ uint8_t byte;
+ char *tmp;
+ int i;
+
+ /* Calculate abbreviation threshold, if any */
+ count = ( size * sizeof ( element ) );
+ threshold = count;
+ if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) {
+ threshold -= ( ( sizeof ( buf ) - 3 /* "..." */
+ - ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ )
+ - 1 /* NUL */ ) / 2 /* "xx" */ );
+ }
+
+ /* Transcribe bytes, abbreviating with "..." if necessary */
+ for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) {
+ element = value->element[ i / sizeof ( element ) ];
+ byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) );
+ tmp += sprintf ( tmp, "%02x", byte );
+ if ( i == threshold ) {
+ tmp += sprintf ( tmp, "..." );
+ i = BIGINT_NTOA_LSB_MIN;
+ }
+ }
+ assert ( tmp < ( buf + sizeof ( buf ) ) );
+
+ return buf;
+}
+
/**
* Conditionally swap big integers (in constant time)
*
diff --git a/src/include/ipxe/bigint.h b/src/include/ipxe/bigint.h
index 2dd99380d..1cc606b89 100644
--- a/src/include/ipxe/bigint.h
+++ b/src/include/ipxe/bigint.h
@@ -41,6 +41,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
/**
+ * Transcribe big integer (for debugging)
+ *
+ * @v value Big integer to be transcribed
+ * @ret string Big integer in string form (may be abbreviated)
+ */
+#define bigint_ntoa( value ) ( { \
+ unsigned int size = bigint_size (value); \
+ bigint_ntoa_raw ( (value)->element, size ); \
+ } )
+
+/**
* Initialise big integer
*
* @v value Big integer to initialise
@@ -360,6 +371,8 @@ bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) {
return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
}
+const char * bigint_ntoa_raw ( const bigint_element_t *value0,
+ unsigned int size );
void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
const void *data, size_t len );
void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,