From 3c2b134fe42bc9d0d3ed4b3154a806fe3947e9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 6 Apr 2017 17:50:39 +0200 Subject: [PATCH] Implement fast increment / decrement functions. --- include/cryb/mpi.h | 8 +++++ lib/mpi/Makefile.am | 4 +++ lib/mpi/cryb_mpi_dec.c | 58 +++++++++++++++++++++++++++++++++ lib/mpi/cryb_mpi_dec_abs.c | 65 ++++++++++++++++++++++++++++++++++++ lib/mpi/cryb_mpi_inc.c | 58 +++++++++++++++++++++++++++++++++ lib/mpi/cryb_mpi_inc_abs.c | 67 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 260 insertions(+) create mode 100644 lib/mpi/cryb_mpi_dec.c create mode 100644 lib/mpi/cryb_mpi_dec_abs.c create mode 100644 lib/mpi/cryb_mpi_inc.c create mode 100644 lib/mpi/cryb_mpi_inc_abs.c diff --git a/include/cryb/mpi.h b/include/cryb/mpi.h index d45d3fd..f0012b1 100644 --- a/include/cryb/mpi.h +++ b/include/cryb/mpi.h @@ -49,6 +49,8 @@ const char *cryb_mpi_version(void); #define mpi_cmp_u32 cryb_mpi_cmp_u32 #define mpi_cmp_u64 cryb_mpi_cmp_u64 #define mpi_copy cryb_mpi_copy +#define mpi_dec cryb_mpi_dec +#define mpi_dec_abs cryb_mpi_dec_abs #define mpi_destroy cryb_mpi_destroy #define mpi_eq cryb_mpi_eq #define mpi_eq_abs cryb_mpi_eq_abs @@ -60,6 +62,8 @@ const char *cryb_mpi_version(void); #define mpi_eq_u64 cryb_mpi_eq_u64 #define mpi_gcd_abs cryb_mpi_gcd_abs #define mpi_grow cryb_mpi_grow +#define mpi_inc cryb_mpi_inc +#define mpi_inc_abs cryb_mpi_inc_abs #define mpi_init cryb_mpi_init #define mpi_load cryb_mpi_load #define mpi_lsb cryb_mpi_lsb @@ -99,6 +103,8 @@ int mpi_cmp_i64(const cryb_mpi *, int64_t); int mpi_cmp_u32(const cryb_mpi *, uint32_t); int mpi_cmp_u64(const cryb_mpi *, uint64_t); int mpi_copy(cryb_mpi *, const cryb_mpi *); +int mpi_dec(cryb_mpi *); +int mpi_dec_abs(cryb_mpi *); void mpi_destroy(cryb_mpi *); int mpi_eq(const cryb_mpi *, const cryb_mpi *); int mpi_eq_abs(const cryb_mpi *, const cryb_mpi *); @@ -110,6 +116,8 @@ int mpi_eq_u32(const cryb_mpi *, uint32_t); int mpi_eq_u64(const cryb_mpi *, uint64_t); int mpi_gcd_abs(cryb_mpi *, const cryb_mpi *, const cryb_mpi *); int mpi_grow(cryb_mpi *, unsigned int); +int mpi_inc(cryb_mpi *); +int mpi_inc_abs(cryb_mpi *); void mpi_init(cryb_mpi *); int mpi_load(cryb_mpi *, const uint8_t *, size_t); unsigned int mpi_lsb(const cryb_mpi *); diff --git a/lib/mpi/Makefile.am b/lib/mpi/Makefile.am index df4c455..bca426d 100644 --- a/lib/mpi/Makefile.am +++ b/lib/mpi/Makefile.am @@ -10,6 +10,8 @@ libcryb_mpi_la_SOURCES = \ cryb_mpi_cmp_i32.c \ cryb_mpi_cmp_i64.c \ cryb_mpi_copy.c \ + cryb_mpi_dec.c \ + cryb_mpi_dec_abs.c \ cryb_mpi_destroy.c \ cryb_mpi_eq.c \ cryb_mpi_eq_abs.c \ @@ -17,6 +19,8 @@ libcryb_mpi_la_SOURCES = \ cryb_mpi_eq_i64.c \ cryb_mpi_gcd_abs.c \ cryb_mpi_grow.c \ + cryb_mpi_inc.c \ + cryb_mpi_inc_abs.c \ cryb_mpi_init.c \ cryb_mpi_load.c \ cryb_mpi_lsb.c \ diff --git a/lib/mpi/cryb_mpi_dec.c b/lib/mpi/cryb_mpi_dec.c new file mode 100644 index 0000000..9a4f1ea --- /dev/null +++ b/lib/mpi/cryb_mpi_dec.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cryb/impl.h" + +#include +#include +#include + +#include +#include + +#include "cryb_mpi_impl.h" + +/* + * Decrement X in place. + */ +int +mpi_dec(cryb_mpi *X) +{ + + if (X->msb == 0) { + mpi_set(X, -1); + } else if (X->neg) { + if (mpi_inc_abs(X) != 0) + return (-1); + } else { + if (mpi_dec_abs(X) != 0) + return (-1); + } + return (0); +} diff --git a/lib/mpi/cryb_mpi_dec_abs.c b/lib/mpi/cryb_mpi_dec_abs.c new file mode 100644 index 0000000..2463c60 --- /dev/null +++ b/lib/mpi/cryb_mpi_dec_abs.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cryb/impl.h" + +#include +#include +#include +#include + +#include +#include + +#include "cryb_mpi_impl.h" + +/* + * Decrement X in place. + */ +int +mpi_dec_abs(cryb_mpi *X) +{ + unsigned int i; + + /* trivial case: zero */ + if (X->msb == 0) { + errno = EINVAL; + return (-1); + } + + /* decrement least-significant word and propagate */ + for (i = 0; X->words[i]-- == 0; ++i) + /* nothing */; + i = X->msb / 32; + if (X->words[i] == 0) + --i; + X->msb = i * 32 + flsl(X->words[i]); + + return (0); +} diff --git a/lib/mpi/cryb_mpi_inc.c b/lib/mpi/cryb_mpi_inc.c new file mode 100644 index 0000000..95f97d8 --- /dev/null +++ b/lib/mpi/cryb_mpi_inc.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cryb/impl.h" + +#include +#include +#include + +#include +#include + +#include "cryb_mpi_impl.h" + +/* + * Increment X in place. + */ +int +mpi_inc(cryb_mpi *X) +{ + + if (X->msb == 0) { + mpi_set(X, 1); + } else if (X->neg) { + if (mpi_dec_abs(X) != 0) + return (-1); + } else { + if (mpi_inc_abs(X) != 0) + return (-1); + } + return (0); +} diff --git a/lib/mpi/cryb_mpi_inc_abs.c b/lib/mpi/cryb_mpi_inc_abs.c new file mode 100644 index 0000000..455a87d --- /dev/null +++ b/lib/mpi/cryb_mpi_inc_abs.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017 Dag-Erling Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cryb/impl.h" + +#include +#include +#include + +#include +#include + +#include "cryb_mpi_impl.h" + +/* + * Increment X in place. + */ +int +mpi_inc_abs(cryb_mpi *X) +{ + unsigned int i; + + /* trivial case: zero */ + if (X->msb == 0) { + X->words[0] = 1; + X->msb = 1; + return (0); + } + + /* may grow by 1 bit */ + if (mpi_grow(X, X->msb + 1) != 0) + return (-1); + + /* increment least-significant word and propagate */ + for (i = 0; ++X->words[i] == 0; ++i) + /* nothing */; + i = X->msb / 32; + X->msb = i * 32 + flsl(X->words[i]); + + return (0); +}