Skip to content

Commit

Permalink
Merge pull request #38 from hololeap/main
Browse files Browse the repository at this point in the history
Update decaf library
  • Loading branch information
kazu-yamamoto authored Oct 17, 2024
2 parents 897d9c2 + b6bac16 commit 593395e
Show file tree
Hide file tree
Showing 14 changed files with 1,090 additions and 757 deletions.
473 changes: 226 additions & 247 deletions cbits/decaf/ed448goldilocks/decaf.c

Large diffs are not rendered by default.

552 changes: 276 additions & 276 deletions cbits/decaf/ed448goldilocks/decaf_tables.c

Large diffs are not rendered by default.

136 changes: 114 additions & 22 deletions cbits/decaf/ed448goldilocks/eddsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,13 @@
#define NO_CONTEXT CRYPTON_DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
#define EDDSA_USE_SIGMA_ISOGENY 0
#define COFACTOR 4
#define EDDSA_PREHASH_BYTES 64

#if NO_CONTEXT
const uint8_t CRYPTON_NO_CONTEXT_POINTS_HERE = 0;
const uint8_t * const CRYPTON_DECAF_ED448_NO_CONTEXT = &CRYPTON_NO_CONTEXT_POINTS_HERE;
#endif

/* EDDSA_BASE_POINT_RATIO = 1 or 2
* Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
* its base point is twice ours.
*/
#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY)

static void clamp (
uint8_t secret_scalar_ser[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES]
) {
Expand Down Expand Up @@ -128,22 +123,22 @@ void crypton_decaf_ed448_derive_public_key (
* the decaf base point is on Etwist_d, and when converted it effectively
* picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1.
*/
for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c=1; c<CRYPTON_DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(secret_scalar,secret_scalar);
}

API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);

API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);

/* Cleanup */
API_NS(scalar_destroy)(secret_scalar);
API_NS(point_destroy)(p);
crypton_decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser));
}

void crypton_decaf_ed448_sign (
static void crypton_decaf_ed448_sign_internal (
uint8_t signature[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES],
Expand Down Expand Up @@ -191,13 +186,13 @@ void crypton_decaf_ed448_sign (
/* Scalarmul to create the nonce-point */
API_NS(scalar_t) nonce_scalar_2;
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
for (unsigned int c = 2; c < CRYPTON_DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
}

API_NS(point_t) p;
API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
API_NS(point_destroy)(p);
API_NS(scalar_destroy)(nonce_scalar_2);
}
Expand Down Expand Up @@ -228,6 +223,24 @@ void crypton_decaf_ed448_sign (
API_NS(scalar_destroy)(challenge_scalar);
}

void crypton_decaf_ed448_sign (
uint8_t signature[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES],
const uint8_t privkey[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES],
const uint8_t pubkey[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES],
const uint8_t *message,
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
uint8_t context_len
) {
uint8_t rederived_pubkey[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES];
crypton_decaf_ed448_derive_public_key(rederived_pubkey, privkey);
if (CRYPTON_DECAF_TRUE != crypton_decaf_memeq(rederived_pubkey, pubkey, sizeof(rederived_pubkey))) {
abort();
}
crypton_decaf_ed448_sign_internal(signature,privkey,rederived_pubkey,message,
message_len,prehashed,context,context_len);
}

void crypton_decaf_ed448_sign_prehash (
uint8_t signature[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES],
Expand All @@ -237,15 +250,83 @@ void crypton_decaf_ed448_sign_prehash (
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
crypton_decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
hash_final(hash_too,hash_output,sizeof(hash_output));
hash_destroy(hash_too);
}

uint8_t rederived_pubkey[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES];
crypton_decaf_ed448_derive_public_key(rederived_pubkey, privkey);
if (CRYPTON_DECAF_TRUE != crypton_decaf_memeq(rederived_pubkey, pubkey, sizeof(rederived_pubkey))) {
abort();
}

crypton_decaf_ed448_sign_internal(signature,privkey,rederived_pubkey,hash_output,
sizeof(hash_output),1,context,context_len);
crypton_decaf_bzero(hash_output,sizeof(hash_output));
}

void crypton_decaf_ed448_derive_keypair (
crypton_decaf_eddsa_448_keypair_t keypair,
const uint8_t privkey[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES]
) {
memcpy(keypair->privkey, privkey, CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES);
crypton_decaf_ed448_derive_public_key(keypair->pubkey, keypair->privkey);
}

void crypton_decaf_ed448_keypair_extract_public_key (
uint8_t pubkey[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES],
const crypton_decaf_eddsa_448_keypair_t keypair
) {
memcpy(pubkey,keypair->pubkey,CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES);
}

void crypton_decaf_ed448_keypair_extract_private_key (
uint8_t privkey[CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES],
const crypton_decaf_eddsa_448_keypair_t keypair
) {
memcpy(privkey,keypair->privkey,CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES);
}

void crypton_decaf_ed448_keypair_destroy (
crypton_decaf_eddsa_448_keypair_t keypair
) {
crypton_decaf_bzero(keypair, sizeof(crypton_decaf_eddsa_448_keypair_t));
}

void crypton_decaf_ed448_keypair_sign (
uint8_t signature[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES],
const crypton_decaf_eddsa_448_keypair_t keypair,
const uint8_t *message,
size_t message_len,
uint8_t prehashed,
const uint8_t *context,
uint8_t context_len
) {
crypton_decaf_ed448_sign_internal(signature,keypair->privkey,keypair->pubkey,message,
message_len,prehashed,context,context_len);
}

void crypton_decaf_ed448_keypair_sign_prehash (
uint8_t signature[CRYPTON_DECAF_EDDSA_448_SIGNATURE_BYTES],
const crypton_decaf_eddsa_448_keypair_t keypair,
const crypton_decaf_ed448_prehash_ctx_t hash,
const uint8_t *context,
uint8_t context_len
) {
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
crypton_decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
hash_final(hash_too,hash_output,sizeof(hash_output));
hash_destroy(hash_too);
}

crypton_decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len);
crypton_decaf_ed448_sign_internal(signature,keypair->privkey,keypair->pubkey,hash_output,
sizeof(hash_output),1,context,context_len);
crypton_decaf_bzero(hash_output,sizeof(hash_output));
}

Expand All @@ -259,10 +340,10 @@ crypton_decaf_error_t crypton_decaf_ed448_verify (
uint8_t context_len
) {
API_NS(point_t) pk_point, r_point;
crypton_decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey);
crypton_decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
if (CRYPTON_DECAF_SUCCESS != error) { return error; }

error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature);
error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
if (CRYPTON_DECAF_SUCCESS != error) { return error; }

API_NS(scalar_t) challenge_scalar;
Expand All @@ -282,15 +363,26 @@ crypton_decaf_error_t crypton_decaf_ed448_verify (
API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar);

API_NS(scalar_t) response_scalar;
API_NS(scalar_decode_long)(
error = API_NS(scalar_decode)(
response_scalar,
&signature[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES],
CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES
&signature[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES]
);
#if EDDSA_BASE_POINT_RATIO == 2
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
if (CRYPTON_DECAF_SUCCESS != error) { return error; }

#if CRYPTON_DECAF_448_SCALAR_BYTES < CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES
for (unsigned i = CRYPTON_DECAF_448_SCALAR_BYTES;
i < CRYPTON_DECAF_EDDSA_448_PRIVATE_BYTES;
i++) {
if (signature[CRYPTON_DECAF_EDDSA_448_PUBLIC_BYTES+i] != 0x00) {
return CRYPTON_DECAF_FAILURE;
}
}
#endif

for (unsigned c=1; c<CRYPTON_DECAF_448_EDDSA_DECODE_RATIO; c<<=1) {
API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
}


/* pk_point = -c(x(P)) + (cx + k)G = kG */
API_NS(base_double_scalarmul_non_secret)(
Expand All @@ -312,7 +404,7 @@ crypton_decaf_error_t crypton_decaf_ed448_verify_prehash (
) {
crypton_decaf_error_t ret;

uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */
uint8_t hash_output[EDDSA_PREHASH_BYTES];
{
crypton_decaf_ed448_prehash_ctx_t hash_too;
memcpy(hash_too,hash,sizeof(hash_too));
Expand Down
32 changes: 16 additions & 16 deletions cbits/decaf/ed448goldilocks/scalar.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ static CRYPTON_DECAF_NOINLINE void sc_subx(
unsigned int i;
for (i=0; i<SCALAR_LIMBS; i++) {
chain = (chain + accum[i]) - sub->limb[i];
out->limb[i] = chain;
out->limb[i] = (crypton_decaf_word_t)chain;
chain >>= WBITS;
}
crypton_decaf_word_t borrow = chain+extra; /* = 0 or -1 */
crypton_decaf_word_t borrow = (crypton_decaf_word_t)chain+extra; /* = 0 or -1 */

chain = 0;
for (i=0; i<SCALAR_LIMBS; i++) {
chain = (chain + out->limb[i]) + (p->limb[i] & borrow);
out->limb[i] = chain;
out->limb[i] = (crypton_decaf_word_t)chain;
chain >>= WBITS;
}
}
Expand All @@ -77,22 +77,22 @@ static CRYPTON_DECAF_NOINLINE void sc_montmul (
crypton_decaf_dword_t chain = 0;
for (j=0; j<SCALAR_LIMBS; j++) {
chain += ((crypton_decaf_dword_t)mand)*mier[j] + accum[j];
accum[j] = chain;
accum[j] = (crypton_decaf_word_t)chain;
chain >>= WBITS;
}
accum[j] = chain;
accum[j] = (crypton_decaf_word_t)chain;

mand = accum[0] * MONTGOMERY_FACTOR;
chain = 0;
mier = sc_p->limb;
for (j=0; j<SCALAR_LIMBS; j++) {
chain += (crypton_decaf_dword_t)mand*mier[j] + accum[j];
if (j) accum[j-1] = chain;
if (j) accum[j-1] = (crypton_decaf_word_t)chain;
chain >>= WBITS;
}
chain += accum[j];
chain += hi_carry;
accum[j-1] = chain;
accum[j-1] = (crypton_decaf_word_t)chain;
hi_carry = chain >> WBITS;
}

Expand Down Expand Up @@ -121,7 +121,7 @@ crypton_decaf_error_t API_NS(scalar_invert) (
* Sliding window is fine here because the modulus isn't secret.
*/
const int SCALAR_WINDOW_BITS = 3;
scalar_t precmp[1<<SCALAR_WINDOW_BITS];
scalar_t precmp[1<<3]; // Rewritten from SCALAR_WINDOW_BITS for windows compatibility
const int LAST = (1<<SCALAR_WINDOW_BITS)-1;

/* Precompute precmp = [a^1,a^3,...] */
Expand Down Expand Up @@ -190,10 +190,10 @@ void API_NS(scalar_add) (
unsigned int i;
for (i=0; i<SCALAR_LIMBS; i++) {
chain = (chain + a->limb[i]) + b->limb[i];
out->limb[i] = chain;
out->limb[i] = (crypton_decaf_word_t)chain;
chain >>= WBITS;
}
sc_subx(out, out->limb, sc_p, sc_p, chain);
sc_subx(out, out->limb, sc_p, sc_p, (crypton_decaf_word_t)chain);
}

void
Expand All @@ -204,7 +204,7 @@ API_NS(scalar_set_unsigned) (
memset(out,0,sizeof(scalar_t));
unsigned int i = 0;
for (; i<sizeof(uint64_t)/sizeof(crypton_decaf_word_t); i++) {
out->limb[i] = w;
out->limb[i] = (crypton_decaf_word_t)w;
#if CRYPTON_DECAF_WORD_BITS < 64
w >>= 8*sizeof(crypton_decaf_word_t);
#endif
Expand All @@ -227,7 +227,7 @@ API_NS(scalar_eq) (
static CRYPTON_DECAF_INLINE void scalar_decode_short (
scalar_t s,
const unsigned char *ser,
unsigned int nbytes
size_t nbytes
) {
unsigned int i,j,k=0;
for (i=0; i<SCALAR_LIMBS; i++) {
Expand All @@ -253,7 +253,7 @@ crypton_decaf_error_t API_NS(scalar_decode)(

API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */

return crypton_decaf_succeed_if(~word_is_zero(accum));
return crypton_decaf_succeed_if(~word_is_zero((crypton_decaf_word_t)accum));
}

void API_NS(scalar_destroy) (
Expand Down Expand Up @@ -325,17 +325,17 @@ void API_NS(scalar_halve) (
scalar_t out,
const scalar_t a
) {
crypton_decaf_word_t mask = -(a->limb[0] & 1);
crypton_decaf_word_t mask = bit_to_mask((a->limb[0]) & 1);
crypton_decaf_dword_t chain = 0;
unsigned int i;
for (i=0; i<SCALAR_LIMBS; i++) {
chain = (chain + a->limb[i]) + (sc_p->limb[i] & mask);
out->limb[i] = chain;
out->limb[i] = (crypton_decaf_word_t)chain;
chain >>= CRYPTON_DECAF_WORD_BITS;
}
for (i=0; i<SCALAR_LIMBS-1; i++) {
out->limb[i] = out->limb[i]>>1 | out->limb[i+1]<<(WBITS-1);
}
out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1);
out->limb[i] = out->limb[i]>>1 | (crypton_decaf_word_t)(chain<<(WBITS-1));
}

5 changes: 5 additions & 0 deletions cbits/decaf/include/arch_32/arch_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

#define ARCH_WORD_BITS 32

#if defined _MSC_VER
#define __attribute(x)
#define __inline__ __inline
#endif // MSVC

static __inline__ __attribute((always_inline,unused))
uint32_t word_is_zero(uint32_t a) {
/* let's hope the compiler isn't clever enough to optimize this. */
Expand Down
Loading

0 comments on commit 593395e

Please sign in to comment.