From c9abcef05599b1adb677e491040baac1fb86cf72 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Wed, 27 Jan 2016 16:39:13 -0800 Subject: [PATCH] add some pathological test cases, clearing a few TODO items. Also scalar_set_unsigned now takes a uint64_t instead of a word_t --- src/decaf.c | 12 +++- src/gen_headers/decaf_h.py | 4 +- src/gen_headers/decaf_hxx.py | 26 ++++++-- test/test_decaf.cxx | 123 ++++++++++++++++++++++++++++++++--- 4 files changed, 145 insertions(+), 20 deletions(-) diff --git a/src/decaf.c b/src/decaf.c index 5594282..7335fbd 100644 --- a/src/decaf.c +++ b/src/decaf.c @@ -356,10 +356,18 @@ sc_halve ( void API_NS(scalar_set_unsigned) ( scalar_t out, - decaf_word_t w + uint64_t w ) { memset(out,0,sizeof(scalar_t)); - out->limb[0] = w; + if (sizeof(uint64_t) > sizeof(decaf_word_t)) { + unsigned int i = 0; + for (; ilimb[i] = w; + w >>= 8*sizeof(decaf_word_t); + } + } else { + out->limb[0] = w; + } } decaf_bool_t diff --git a/src/gen_headers/decaf_h.py b/src/gen_headers/decaf_h.py index ea95d51..8978e98 100644 --- a/src/gen_headers/decaf_h.py +++ b/src/gen_headers/decaf_h.py @@ -199,13 +199,13 @@ static inline void NONNULL2 %(c_ns)s_scalar_copy ( } /** - * @brief Set a scalar to an unsigned integer. + * @brief Set a scalar to an unsigned 64-bit integer. * @param [in] a An integer. * @param [out] out Will become equal to a. */ void %(c_ns)s_scalar_set_unsigned ( %(c_ns)s_scalar_t out, - decaf_word_t a + uint64_t a ) API_VIS NONNULL1; /** diff --git a/src/gen_headers/decaf_hxx.py b/src/gen_headers/decaf_hxx.py index 8a09648..735bc8e 100644 --- a/src/gen_headers/decaf_hxx.py +++ b/src/gen_headers/decaf_hxx.py @@ -81,10 +81,16 @@ public: /** @endcond */ /** Set to an unsigned word */ - inline Scalar(const decaf_word_t w) NOEXCEPT { *this = w; } + inline Scalar(uint64_t w) NOEXCEPT { *this = w; } /** Set to a signed word */ - inline Scalar(const int w) NOEXCEPT { *this = w; } + inline Scalar(int64_t w) NOEXCEPT { *this = w; } + + /** Set to an unsigned word */ + inline Scalar(unsigned int w) NOEXCEPT { *this = w; } + + /** Set to a signed word */ + inline Scalar(int w) NOEXCEPT { *this = w; } /** Construct from RNG */ inline explicit Scalar(Rng &rng) NOEXCEPT { @@ -112,18 +118,24 @@ public: /** Assignment. */ inline Scalar& operator=(const Scalar &x) NOEXCEPT { %(c_ns)s_scalar_copy(s,x.s); return *this; } - /** Assign from unsigned word. */ - inline Scalar& operator=(decaf_word_t w) NOEXCEPT { %(c_ns)s_scalar_set_unsigned(s,w); return *this; } + /** Assign from unsigned 64-bit integer. */ + inline Scalar& operator=(uint64_t w) NOEXCEPT { %(c_ns)s_scalar_set_unsigned(s,w); return *this; } /** Assign from signed int. */ - inline Scalar& operator=(int w) NOEXCEPT { - Scalar t(-(decaf_word_t)INT_MIN); - %(c_ns)s_scalar_set_unsigned(s,(decaf_word_t)w - (decaf_word_t)INT_MIN); + inline Scalar& operator=(int64_t w) NOEXCEPT { + Scalar t(-(uint64_t)INT_MIN); + %(c_ns)s_scalar_set_unsigned(s,(uint64_t)w - (uint64_t)INT_MIN); *this -= t; return *this; } + /** Assign from unsigned int. */ + inline Scalar& operator=(unsigned int w) NOEXCEPT { return *this = (uint64_t)w; } + + /** Assign from signed int. */ + inline Scalar& operator=(int w) NOEXCEPT { return *this = (int64_t)w; } + /** Destructor securely zeorizes the scalar. */ inline ~Scalar() NOEXCEPT { %(c_ns)s_scalar_destroy(s); } diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index afc3081..17f8651 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -43,6 +43,14 @@ public: } }; +static uint64_t leint(const SecureBuffer &xx) { + uint64_t out = 0; + for (unsigned int i=0; i struct Tests { typedef typename Group::Scalar Scalar; @@ -137,16 +145,20 @@ static void test_arithmetic() { arith_check(test,x,y,z,INT_MIN,-Scalar(1+(decaf_word_t)INT_MAX),"cast from min"); for (int i=0; i= Point::HASH_BYTES) b1[Point::HASH_BYTES-1] &= 0x7F; // FIXME MAGIC + /* Pathological cases */ + if (i==1) b1[0] = 1; + if (i==2 && sqrt_minus_one.size()) b1 = sqrt_minus_one; + if (i==3 && minus_sqrt_minus_one.size()) b1 = minus_sqrt_minus_one; + if (i==4 && elli_patho.size()) b1 = elli_patho; + len = b1.size(); + + Point s = Point::from_hash(b1), ss=s; for (int j=0; j<(i&3); j++) ss = ss.debugging_torque(); @@ -273,6 +308,8 @@ static void test_ec() { Point id = Point::identity(), base = Point::base(); point_check(test,id,id,id,0,0,Point::from_hash(""),id,"fh0"); + unsigned char enc[Point::SER_BYTES] = {0}; + if (Group::FIELD_MODULUS_TYPE == 3) { /* When p == 3 mod 4, the QNR is -1, so u*1^2 = -1 also produces the * identity. @@ -280,8 +317,37 @@ static void test_ec() { point_check(test,id,id,id,0,0,Point::from_hash("\x01"),id,"fh1"); } + point_check(test,id,id,id,0,0,Point(FixedBlock(enc)),id,"decode [0]"); + try { + enc[0] = 1; + Point f((FixedBlock(enc))); + test.fail(); + printf(" Allowed deserialize of [1]: %d", f==id); + } catch (CryptoException) { + /* ok */ + } + + if (sqrt_minus_one.size()) { + try { + Point f(sqrt_minus_one); + test.fail(); + printf(" Allowed deserialize of [i]: %d", f==id); + } catch (CryptoException) { + /* ok */ + } + } + + if (minus_sqrt_minus_one.size()) { + try { + Point f(minus_sqrt_minus_one); + test.fail(); + printf(" Allowed deserialize of [-i]: %d", f==id); + } catch (CryptoException) { + /* ok */ + } + } + for (int i=0; i const uint8_t Tests::rfc7748_1000000[56] = { 0xc9,0x46,0xda,0x8d,0x52,0x4d,0xe3,0xd6, 0x9b,0xd9,0xd9,0xd6,0x6b,0x99,0x7e,0x37 }; + +template<> const Block Tests::sqrt_minus_one(NULL,0); +const uint8_t sm1_25519[32] = { + 0xb0,0xa0,0x0e,0x4a,0x27,0x1b,0xee,0xc4, + 0x78,0xe4,0x2f,0xad,0x06,0x18,0x43,0x2f, + 0xa7,0xd7,0xfb,0x3d,0x99,0x00,0x4d,0x2b, + 0x0b,0xdf,0xc1,0x4f,0x80,0x24,0x83,0x2b +}; +template<> const Block Tests::sqrt_minus_one(sm1_25519,32); + +template<> const Block Tests::minus_sqrt_minus_one(NULL,0); +const uint8_t msm1_25519[32] = { + 0x3d,0x5f,0xf1,0xb5,0xd8,0xe4,0x11,0x3b, + 0x87,0x1b,0xd0,0x52,0xf9,0xe7,0xbc,0xd0, + 0x58,0x28,0x04,0xc2,0x66,0xff,0xb2,0xd4, + 0xf4,0x20,0x3e,0xb0,0x7f,0xdb,0x7c,0x54 +}; +template<> const Block Tests::minus_sqrt_minus_one(msm1_25519,32); + +const uint8_t elli_patho_448[56] = { + 0x14,0xf0,0x70,0x58,0x41,0xc7,0xf9,0xa5, + 0xfa,0x2c,0x7d,0x87,0x07,0x89,0xe8,0x61, + 0x63,0xe8,0xc8,0xdc,0x06,0x2d,0x39,0x8f, + 0x18,0x83,0x1e,0xc6,0x8c,0x6d,0x73,0x24, + 0xd4,0xb3,0xd3,0xe1,0xf3,0x51,0x8c,0xee, + 0x65,0x79,0x88,0xc1,0x0b,0xcf,0x8e,0xa5, + 0x86,0xa9,0x2e,0xc9,0x17,0x68,0x9b,0x20 +}; +template<> const Block Tests::elli_patho(elli_patho_448,56); +template<> const Block Tests::elli_patho(NULL,0);