Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update decaf library #38

Merged
merged 3 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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