diff --git a/include/cryb/mpi.h b/include/cryb/mpi.h index ba657b2..e10f4c8 100644 --- a/include/cryb/mpi.h +++ b/include/cryb/mpi.h @@ -55,7 +55,9 @@ int mpi_set(cryb_mpi *, int32_t); int mpi_lshift(cryb_mpi *, unsigned int); int mpi_rshift(cryb_mpi *, unsigned int); int mpi_add_abs(cryb_mpi *, cryb_mpi *, cryb_mpi *); +int mpi_add(cryb_mpi *, cryb_mpi *, cryb_mpi *); int mpi_sub_abs(cryb_mpi *, cryb_mpi *, cryb_mpi *); +int mpi_sub(cryb_mpi *, cryb_mpi *, cryb_mpi *); int mpi_cmp_abs(cryb_mpi *, cryb_mpi *); int mpi_cmp(cryb_mpi *, cryb_mpi *); int mpi_eq_abs(cryb_mpi *, cryb_mpi *); diff --git a/lib/mpi/mpi_add.c b/lib/mpi/mpi_add.c index 465d76b..7a0579e 100644 --- a/lib/mpi/mpi_add.c +++ b/lib/mpi/mpi_add.c @@ -97,3 +97,31 @@ mpi_add_abs(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) X->msb += i * 32 + 1; return (0); } + +/* + * Add two numbers together. + */ +int +mpi_add(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) +{ + + if (A->neg && B->neg) { + if (mpi_add_abs(X, A, B) < 0) + return (-1); + X->neg = 1; + } else if (A->neg) { + if (mpi_sub_abs(X, A, B) < 0) + return (-1); + X->neg = (mpi_cmp_abs(A, B) < 0); + } else if (B->neg) { + if (mpi_sub_abs(X, A, B) < 0) + return (-1); + X->neg = (mpi_cmp_abs(A, B) > 0); + } else { + if (mpi_add_abs(X, A, B) < 0) + return (-1); + X->neg = 0; + } + return (0); +} + diff --git a/lib/mpi/mpi_sub.c b/lib/mpi/mpi_sub.c index 5777943..41b889f 100644 --- a/lib/mpi/mpi_sub.c +++ b/lib/mpi/mpi_sub.c @@ -92,3 +92,30 @@ mpi_sub_abs(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) X->msb += i * 32 + 1; return (0); } + +/* + * Subtract one number from another. + */ +int +mpi_sub(cryb_mpi *X, cryb_mpi *A, cryb_mpi *B) +{ + + if (A->neg && B->neg) { + if (mpi_sub_abs(X, A, B) < 0) + return (-1); + X->neg = (mpi_cmp_abs(A, B) > 0); + } else if (A->neg) { + if (mpi_add_abs(X, A, B) < 0) + return (-1); + X->neg = 1; + } else if (B->neg) { + if (mpi_add_abs(X, A, B) < 0) + return (-1); + X->neg = 0; + } else { + if (mpi_sub_abs(X, A, B) < 0) + return (-1); + X->neg = (mpi_cmp_abs(A, B) < 0); + } + return (0); +}