Browse Source

decaf signatures, but they dont work yet

master
Michael Hamburg 10 years ago
parent
commit
4eb8567730
3 changed files with 204 additions and 1 deletions
  1. +63
    -0
      include/decaf_crypto.h
  2. +116
    -1
      src/decaf_crypto.c
  3. +25
    -0
      test/bench.c

+ 63
- 0
include/decaf_crypto.h View File

@@ -31,6 +31,9 @@ typedef unsigned char decaf_448_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES];
/** An encoded public key. */
typedef unsigned char decaf_448_public_key_t[DECAF_448_SER_BYTES];

/** A signature. */
typedef unsigned char decaf_448_signature_t[DECAF_448_SER_BYTES + DECAF_448_SCALAR_BYTES];

/** A private key. */
typedef struct {
decaf_448_symmetric_key_t sym;
@@ -90,6 +93,66 @@ decaf_448_shared_secret (
const decaf_448_private_key_t my_privkey,
const decaf_448_public_key_t your_pubkey
) NONNULL134 WARN_UNUSED API_VIS;
/**
* @brief Sign a message from its SHAKE context.
*
* @param [out] sig The signature.
* @param [in] priv Your private key.
* @param [in] shake A SHAKE256 context with the message.
*/
void
decaf_448_sign_shake (
decaf_448_signature_t sig,
const decaf_448_private_key_t priv,
const keccak_sponge_t shake
) NONNULL3 API_VIS;

/**
* @brief Sign a message from its SHAKE context.
*
* @param [out] sig The signature.
* @param [in] priv Your private key.
* @param [in] message The message.
* @param [in] message_len The message's length.
*/
void
decaf_448_sign (
decaf_448_signature_t sig,
const decaf_448_private_key_t priv,
const unsigned char *message,
size_t message_len
) NONNULL3 API_VIS;

/**
* @brief Verify a signed message from its SHAKE context.
*
* @param [in] sig The signature.
* @param [in] pub The public key.
* @param [in] shake A SHAKE256 context with the message.
*/
decaf_bool_t
decaf_448_verify_shake (
const decaf_448_signature_t sig,
const decaf_448_public_key_t pub,
const keccak_sponge_t shake
) NONNULL3 API_VIS WARN_UNUSED;

/**
* @brief Verify a signed message.
*
* @param [in] sig The signature.
* @param [in] pub The public key.
* @param [in] message The message.
* @param [in] message_len The message's length.
*/
decaf_bool_t
decaf_448_verify (
const decaf_448_signature_t sig,
const decaf_448_public_key_t pub,
const unsigned char *message,
size_t message_len
) NONNULL3 API_VIS WARN_UNUSED;
#undef API_VIS
#undef WARN_UNUSED


+ 116
- 1
src/decaf_crypto.c View File

@@ -11,13 +11,15 @@
#include "decaf_crypto.h"
#include <string.h>

static const unsigned int DECAF_448_SCALAR_OVERKILL_BYTES = DECAF_448_SCALAR_BYTES + 8;

void decaf_448_derive_private_key (
decaf_448_private_key_t priv,
const decaf_448_symmetric_key_t proto
) {
const char *magic = "decaf_448_derive_private_key";
keccak_sponge_t sponge;
uint8_t encoded_scalar[64];
uint8_t encoded_scalar[DECAF_448_SCALAR_OVERKILL_BYTES];
decaf_448_point_t pub;
shake256_init(sponge);
shake256_update(sponge, proto, sizeof(decaf_448_symmetric_key_t));
@@ -114,3 +116,116 @@ decaf_448_shared_secret (
return ret;
}

void
decaf_448_sign_shake (
decaf_448_signature_t sig,
const decaf_448_private_key_t priv,
const keccak_sponge_t shake
) {
const char *magic = "decaf_448_sign_shake";

uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES], encoded[DECAF_448_SER_BYTES];
decaf_448_point_t point;
decaf_448_scalar_t nonce, challenge;
/* Derive nonce */
keccak_sponge_t ctx;
memcpy(ctx, shake, sizeof(ctx));
shake256_update(ctx, priv->sym, sizeof(priv->sym));
shake256_update(ctx, (const unsigned char *)magic, strlen(magic));
shake256_final(ctx, overkill, sizeof(overkill));
decaf_448_scalar_decode_long(nonce, overkill, sizeof(overkill));
decaf_448_precomputed_scalarmul(point, decaf_448_precomputed_base, nonce);
decaf_448_point_encode(encoded, point);

/* Derive challenge */
memcpy(ctx, shake, sizeof(ctx));
shake256_update(ctx, priv->pub, sizeof(priv->pub));
shake256_update(ctx, encoded, sizeof(encoded));
shake256_final(ctx, overkill, sizeof(overkill));
shake256_destroy(ctx);
decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill));
/* Respond */
decaf_448_scalar_mul(challenge, challenge, priv->secret_scalar);
decaf_448_scalar_sub(nonce, nonce, challenge);
/* Save results */
memcpy(sig, encoded, sizeof(encoded));
decaf_448_scalar_encode(&sig[sizeof(encoded)], nonce);
/* Clean up */
decaf_448_scalar_destroy(nonce);
decaf_448_scalar_destroy(challenge);
decaf_bzero(overkill,sizeof(overkill));
decaf_bzero(encoded,sizeof(encoded));
}

decaf_bool_t
decaf_448_verify_shake (
const decaf_448_signature_t sig,
const decaf_448_public_key_t pub,
const keccak_sponge_t shake
) {
decaf_bool_t ret;

uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES];
decaf_448_point_t point, pubpoint;
decaf_448_scalar_t challenge, response;
/* Derive challenge */
keccak_sponge_t ctx;
memcpy(ctx, shake, sizeof(ctx));
shake256_update(ctx, pub, sizeof(decaf_448_public_key_t));
shake256_update(ctx, sig, DECAF_448_SER_BYTES);
shake256_final(ctx, overkill, sizeof(overkill));
shake256_destroy(ctx);
decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill));

/* Decode points. PERF: avoid decode of point? */
ret = decaf_448_point_decode(point, sig, DECAF_TRUE);
ret &= decaf_448_point_decode(pubpoint, pub, DECAF_FALSE);
ret &= decaf_448_scalar_decode(response, &sig[DECAF_448_SER_BYTES]);

decaf_448_point_double_scalarmul (
pubpoint,
decaf_448_point_identity, response,
pubpoint, challenge
);
/* TODO: avoid the decode here? */
ret &= decaf_448_point_eq(pubpoint, point);
return ret;
}

void
decaf_448_sign (
decaf_448_signature_t sig,
const decaf_448_private_key_t priv,
const unsigned char *message,
size_t message_len
) {
keccak_sponge_t ctx;
shake256_init(ctx);
shake256_update(ctx, message, message_len);
decaf_448_sign_shake(sig, priv, ctx);
shake256_destroy(ctx);
}

decaf_bool_t
decaf_448_verify (
const decaf_448_signature_t sig,
const decaf_448_public_key_t pub,
const unsigned char *message,
size_t message_len
) {
keccak_sponge_t ctx;
shake256_init(ctx);
shake256_update(ctx, message, message_len);
decaf_bool_t ret = decaf_448_verify_shake(sig, pub, ctx);
shake256_destroy(ctx);
return ret;
}

+ 25
- 0
test/bench.c View File

@@ -712,5 +712,30 @@ int main(int argc, char **argv) {
printf("BUG: mismatched shared secrets\n");
}
decaf_448_signature_t dsig;
const char *dmessage = "hello world";
const char *dnessage = "Jello world";
when = now();
for (i=0; i<nbase/10; i++) {
decaf_448_sign(dsig, dpriv[0], (const unsigned char *)dmessage, 11);
}
when = now() - when;
printf("sign: %5.1fµs\n", when * 1e6 / i);
when = now();
for (i=0; i<nbase/10; i++) {
decaf_bool_t ret = decaf_448_verify(dsig, dpub[0],
(const unsigned char *)((i&1) ? dmessage : dnessage), 11);
if ((i&1) && ~ret) {
printf("BUG: verify failed\n");
break;
} else if (!(i&1) && ret) {
printf("BUG: unverify succeeded\n");
break;
}
}
when = now() - when;
printf("verify: %5.1fµs\n", when * 1e6 / i);
return 0;
}

Loading…
Cancel
Save