Browse Source

working on securebuffer problems, might just switch things to vector

master
Mike Hamburg 9 years ago
parent
commit
b849d2cd91
5 changed files with 101 additions and 41 deletions
  1. +6
    -5
      src/public_include/decaf/decaf_255.hxx
  2. +4
    -4
      src/public_include/decaf/decaf_448.hxx
  3. +35
    -5
      src/public_include/decaf/secure_buffer.hxx
  4. +11
    -0
      src/public_include/decaf/shake.hxx
  5. +45
    -27
      test/test_decaf.cxx

+ 6
- 5
src/public_include/decaf/decaf_255.hxx View File

@@ -88,7 +88,7 @@ public:
/** @brief Construct from RNG */
inline explicit Scalar(Rng &rng) NOEXCEPT {
StackBuffer<SER_BYTES> sb(rng);
FixedArrayBuffer<SER_BYTES> sb(rng);
*this = sb;
}
@@ -230,10 +230,10 @@ public:
/** @brief Construct from RNG */
inline explicit Point(Rng &rng, bool uniform = true) NOEXCEPT {
if (uniform) {
StackBuffer<2*HASH_BYTES> b(rng);
FixedArrayBuffer<2*HASH_BYTES> b(rng);
set_to_hash(b);
} else {
StackBuffer<HASH_BYTES> b(rng);
FixedArrayBuffer<HASH_BYTES> b(rng);
set_to_hash(b);
}
}
@@ -399,7 +399,7 @@ public:
/** @brief Return a point equal to *this, whose internal data has a randomized representation. */
inline Point debugging_pscale(Rng &r) const NOEXCEPT {
StackBuffer<SER_BYTES> sb(r); return debugging_pscale(sb);
FixedArrayBuffer<SER_BYTES> sb(r); return debugging_pscale(sb);
}
/**
@@ -430,7 +430,8 @@ public:
}
/** @brief Steganographically encode this */
inline SecureBuffer steg_encode(Rng &rng) const throw(std::bad_alloc) {
inline SecureBuffer steg_encode(Rng &rng, size_t size=STEG_BYTES) const throw(std::bad_alloc, LengthException) {
if (size <= HASH_BYTES + 4 || size > 2*HASH_BYTES) throw LengthException();
SecureBuffer out(STEG_BYTES);
bool done;
do {


+ 4
- 4
src/public_include/decaf/decaf_448.hxx View File

@@ -88,7 +88,7 @@ public:
/** @brief Construct from RNG */
inline explicit Scalar(Rng &rng) NOEXCEPT {
StackBuffer<SER_BYTES> sb(rng);
FixedArrayBuffer<SER_BYTES> sb(rng);
*this = sb;
}
@@ -233,10 +233,10 @@ public:
/** @brief Construct from RNG */
inline explicit Point(Rng &rng, bool uniform = true) NOEXCEPT {
if (uniform) {
StackBuffer<2*HASH_BYTES> b(rng);
FixedArrayBuffer<2*HASH_BYTES> b(rng);
set_to_hash(b);
} else {
StackBuffer<HASH_BYTES> b(rng);
FixedArrayBuffer<HASH_BYTES> b(rng);
set_to_hash(b);
}
}
@@ -408,7 +408,7 @@ public:
/** @brief Return a point equal to *this, whose internal data has a randomized representation. */
inline Point debugging_pscale(Rng &r) const NOEXCEPT {
StackBuffer<SER_BYTES> sb(r);
FixedArrayBuffer<SER_BYTES> sb(r);
return debugging_pscale(sb);
}


+ 35
- 5
src/public_include/decaf/secure_buffer.hxx View File

@@ -13,6 +13,7 @@

#include <string>
#include <sys/types.h>
#include <stdio.h>

/** @cond internal */
#if __cplusplus >= 201103L
@@ -146,6 +147,13 @@ public:

/** Virtual destructor for SecureBlock. TODO: probably means vtable? Make bool? */
inline virtual ~Block() {};
/** Debugging print in hex */
inline void debug_print(const char *name = NULL) {
if (name) printf("%s = ", name);
for (size_t s = 0; s < size(); s++) printf("%02x", data_[s]);
printf("\n");
}
};

/** A fixed-size block */
@@ -184,6 +192,12 @@ public:
/** Slice the buffer*/
inline TmpBuffer slice(size_t off, size_t length) throw(LengthException);
/** Copy from another block */
inline void assign(const Block b) throw(LengthException) {
if (b.size() != size()) throw LengthException();
memmove(*this,b,size());
}
/** Securely set the buffer to 0. */
inline void zeroize() NOEXCEPT { really_bzero(data(),size()); }
};
@@ -214,23 +228,39 @@ public:
};

/** A fixed-size stack-allocated buffer (for NOEXCEPT semantics) */
template<size_t Size> class StackBuffer : public FixedBuffer<Size> {
template<size_t Size> class FixedArrayBuffer : public FixedBuffer<Size> {
private:
uint8_t storage[Size];
public:
using Buffer::zeroize;
/** New buffer initialized to zero. */
inline explicit StackBuffer() NOEXCEPT : FixedBuffer<Size>(storage) { memset(storage,0,Size); }
inline explicit FixedArrayBuffer() NOEXCEPT : FixedBuffer<Size>(storage) { memset(storage,0,Size); }

/** New uninitialized buffer. */
inline explicit StackBuffer(const NOINIT &) NOEXCEPT : FixedBuffer<Size>(storage) { }
inline explicit FixedArrayBuffer(const NOINIT &) NOEXCEPT : FixedBuffer<Size>(storage) { }
/** New random buffer */
inline explicit StackBuffer(Rng &r) NOEXCEPT : FixedBuffer<Size>(storage) { r.read(*this); }
inline explicit FixedArrayBuffer(Rng &r) NOEXCEPT : FixedBuffer<Size>(storage) { r.read(*this); }
/** Copy constructor */
inline explicit FixedArrayBuffer(const FixedBlock<Size> &b) NOEXCEPT : FixedBuffer<Size>(storage) {
memcpy(storage,b,Size);
}
/** Copy constructor */
inline explicit FixedArrayBuffer(const Block &b) throw(LengthException) : FixedBuffer<Size>(storage) {
if (b.size() != Size) throw LengthException();
memcpy(storage,b,Size);
}
/** Copy constructor */
inline explicit FixedArrayBuffer(const FixedArrayBuffer<Size> &b) NOEXCEPT : FixedBuffer<Size>(storage) {
memcpy(storage,b,Size);
}
/** Destroy the buffer */
~StackBuffer() NOEXCEPT { zeroize(); }
~FixedArrayBuffer() NOEXCEPT { zeroize(); }
};

/** @cond internal */


+ 11
- 0
src/public_include/decaf/shake.hxx View File

@@ -108,6 +108,12 @@ public:

/** Reset the hash to the empty string */
inline void reset() NOEXCEPT { sponge_init(sp, get_params()); }

/** Hash bytes with this SHA3 instance. TODO: output length? */
static inline SecureBuffer hash(const Block &b) throw(std::bad_alloc) {
SHA3 s; s += b; return s.output();
}
};

/** Variable-output-length SHAKE */
@@ -122,6 +128,11 @@ public:

/** Reset the hash to the empty string */
inline void reset() NOEXCEPT { sponge_init(sp, get_params()); }
/** Hash bytes with this SHAKE instance */
static inline SecureBuffer hash(const Block &b, size_t outlen) throw(std::bad_alloc) {
SHAKE s; s += b; return s.output(outlen);
}
};

/** @cond internal */


+ 45
- 27
test/test_decaf.cxx View File

@@ -12,8 +12,10 @@
#include <decaf.hxx>
#include <decaf/shake.hxx>
#include <decaf/crypto.h>
#include <decaf/crypto.hxx>
#include <stdio.h>

using namespace decaf;

static bool passing = true;
static const long NTESTS = 10000;
@@ -49,7 +51,7 @@ typedef typename Group::Precomputed Precomputed;

static void print(const char *name, const Scalar &x) {
unsigned char buffer[Scalar::SER_BYTES];
x.encode(decaf::FixedBuffer<Scalar::SER_BYTES>(buffer));
x.encode(FixedBuffer<Scalar::SER_BYTES>(buffer));
printf(" %s = 0x", name);
for (int i=sizeof(buffer)-1; i>=0; i--) {
printf("%02x", buffer[i]);
@@ -57,7 +59,7 @@ static void print(const char *name, const Scalar &x) {
printf("\n");
}

static void hexprint(const char *name, const decaf::SecureBuffer &buffer) {
static void hexprint(const char *name, const SecureBuffer &buffer) {
printf(" %s = 0x", name);
for (int i=buffer.size()-1; i>=0; i--) {
printf("%02x", buffer[i]);
@@ -66,7 +68,7 @@ static void hexprint(const char *name, const decaf::SecureBuffer &buffer) {
}

static void print(const char *name, const Point &x) {
decaf::StackBuffer<Point::SER_BYTES> buffer;
FixedArrayBuffer<Point::SER_BYTES> buffer;
x.encode(buffer);
printf(" %s = 0x", name);
for (int i=Point::SER_BYTES-1; i>=0; i--) {
@@ -126,7 +128,7 @@ static bool point_check(
}

static void test_arithmetic() {
decaf::SpongeRng rng(decaf::Block("test_arithmetic"));
SpongeRng rng(Block("test_arithmetic"));
Test test("Arithmetic");
Scalar x(0),y(0),z(0);
@@ -161,18 +163,18 @@ static void test_arithmetic() {
}

static void test_elligator() {
decaf::SpongeRng rng(decaf::Block("test_elligator"));
SpongeRng rng(Block("test_elligator"));
Test test("Elligator");
const int NHINTS = Group::REMOVED_COFACTOR * 2;
decaf::SecureBuffer *alts[NHINTS];
SecureBuffer *alts[NHINTS];
bool successes[NHINTS];
decaf::SecureBuffer *alts2[NHINTS];
SecureBuffer *alts2[NHINTS];
bool successes2[NHINTS];

for (int i=0; i<NTESTS/10 && (test.passing_now || i < 100); i++) {
size_t len = (i % (2*Point::HASH_BYTES + 3));
decaf::SecureBuffer b1(len);
SecureBuffer b1(len);
if (i!=Point::HASH_BYTES) rng.read(b1); /* special test case */
if (i==1) b1[0] = 1; /* special case test */
if (len >= Point::HASH_BYTES) b1[Point::HASH_BYTES-1] &= 0x7F; // FIXME MAGIC
@@ -184,8 +186,8 @@ static void test_elligator() {
bool good = false;
for (int j=0; j<NHINTS; j++) {
alts[j] = new decaf::SecureBuffer(len);
alts2[j] = new decaf::SecureBuffer(len);
alts[j] = new SecureBuffer(len);
alts2[j] = new SecureBuffer(len);

if (len > Point::HASH_BYTES)
memcpy(&(*alts[j])[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES);
@@ -263,7 +265,7 @@ static void test_elligator() {
}

static void test_ec() {
decaf::SpongeRng rng(decaf::Block("test_ec"));
SpongeRng rng(Block("test_ec"));
Test test("EC");

@@ -278,13 +280,13 @@ static void test_ec() {
Point p(rng);
Point q(rng);
decaf::SecureBuffer buffer(2*Point::HASH_BYTES);
SecureBuffer buffer(2*Point::HASH_BYTES);
rng.read(buffer);
Point r = Point::from_hash(buffer);
point_check(test,p,q,r,0,0,p,Point((decaf::SecureBuffer)p),"round-trip");
point_check(test,p,q,r,0,0,p,Point((SecureBuffer)p),"round-trip");
Point pp = p.debugging_torque().debugging_pscale(rng);
if (decaf::SecureBuffer(pp) != decaf::SecureBuffer(p)) {
if (SecureBuffer(pp) != SecureBuffer(p)) {
test.fail();
printf("Fail torque seq test\n");
}
@@ -306,16 +308,30 @@ static void test_ec() {
"unih = hash+add"
);
point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(decaf::SecureBuffer(p))),x*p,"direct mul");
point_check(test,p,q,r,x,0,Point(x.direct_scalarmul(SecureBuffer(p))),x*p,"direct mul");
}
}

}; // template<decaf::GroupId GROUP>
static void test_crypto() {
Test test("Sample crypto");
SpongeRng rng(Block("test_decaf_crypto"));

for (int i=0; i<NTESTS && test.passing_now; i++) {
PrivateKey<Group> priv1(rng), priv2(rng);
PublicKey<Group> pub1(priv1), pub2(priv2);
SecureBuffer message(rng, i);
FixedArrayBuffer<PublicKey<Group>::SIG_BYTES> sig(priv1.sign(message));
pub1.verify(message, sig);
}
}

}; // template<GroupId GROUP>

// FIXME cross-field
static void test_decaf() {
Test test("Sample crypto");
decaf::SpongeRng rng(decaf::Block("test_decaf"));
SpongeRng rng(Block("test_decaf"));

decaf_255_symmetric_key_t proto1,proto2;
decaf_255_private_key_t s1,s2;
@@ -325,8 +341,8 @@ static void test_decaf() {
const char *message = "Hello, world!";

for (int i=0; i<NTESTS && test.passing_now; i++) {
rng.read(decaf::TmpBuffer(proto1,sizeof(proto1)));
rng.read(decaf::TmpBuffer(proto2,sizeof(proto2)));
rng.read(TmpBuffer(proto1,sizeof(proto1)));
rng.read(TmpBuffer(proto2,sizeof(proto2)));
decaf_255_derive_private_key(s1,proto1);
decaf_255_private_to_public(p1,s1);
decaf_255_derive_private_key(s2,proto2);
@@ -350,17 +366,19 @@ static void test_decaf() {
int main(int argc, char **argv) {
(void) argc; (void) argv;
printf("Testing %s:\n", decaf::IsoEd25519::name());
Tests<decaf::IsoEd25519>::test_arithmetic();
Tests<decaf::IsoEd25519>::test_elligator();
Tests<decaf::IsoEd25519>::test_ec();
printf("Testing %s:\n",IsoEd25519::name());
Tests<IsoEd25519>::test_arithmetic();
Tests<IsoEd25519>::test_elligator();
Tests<IsoEd25519>::test_ec();
Tests<IsoEd25519>::test_crypto();
test_decaf();
printf("\n");
printf("Testing %s:\n", decaf::Ed448Goldilocks::name());
Tests<decaf::Ed448Goldilocks>::test_arithmetic();
Tests<decaf::Ed448Goldilocks>::test_elligator();
Tests<decaf::Ed448Goldilocks>::test_ec();
printf("Testing %s:\n", Ed448Goldilocks::name());
Tests<Ed448Goldilocks>::test_arithmetic();
Tests<Ed448Goldilocks>::test_elligator();
Tests<Ed448Goldilocks>::test_ec();
Tests<Ed448Goldilocks>::test_crypto();
if (passing) printf("Passed all tests.\n");


Loading…
Cancel
Save