int _crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, const unsigned char *m, unsigned long long mlen, const unsigned char *sk, int prehashed) { crypto_hash_sha512_state hs; unsigned char az[64]; unsigned char nonce[64]; unsigned char hram[64]; ge25519_p3 R; _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); #ifdef ED25519_NONDETERMINISTIC memcpy(az, sk, 32); _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az); #else crypto_hash_sha512(az, sk, 32); crypto_hash_sha512_update(&hs, az + 32, 32); #endif crypto_hash_sha512_update(&hs, m, mlen); crypto_hash_sha512_final(&hs, nonce); memmove(sig + 32, sk + 32, 32); sc25519_reduce(nonce); ge25519_scalarmult_base(&R, nonce); ge25519_p3_tobytes(sig, &R); _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); crypto_hash_sha512_update(&hs, sig, 64); crypto_hash_sha512_update(&hs, m, mlen); crypto_hash_sha512_final(&hs, hram); sc25519_reduce(hram); _crypto_sign_ed25519_clamp(az); sc25519_muladd(sig + 32, hram, az, nonce); sodium_memzero(az, sizeof az); sodium_memzero(nonce, sizeof nonce); if (siglen_p != NULL) { *siglen_p = 64U; } return 0; }
int crypto_sign_ed25519_tinynacl(unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long n, const unsigned char *skorig) { long long i; unsigned char nonce[64], hram[64], sk[64], pk[32]; ge25519 R; /* compute secret key from seed sk = H(skorig), H = sha512 */ crypto_hash_sha512(sk, skorig, 32); sk[0] &= 248; sk[31] &= 63; sk[31] |= 64; /* copy m to sm, copy secret key and public key */ *smlen = n + 64; for (i = 31; i >= 0; --i) pk[i ] = skorig[i + 32]; for (i = n - 1; i >= 0; --i) sm[i + 64] = m[i]; for (i = 31; i >= 0; --i) sm[i + 32] = sk[i + 32]; /* get pseudorandom nonce = H(sk2, m) */ crypto_hash_sha512(nonce, sm + 32, n + 32); sc25519_reduce(nonce); /* copy pk to sm */ for (i = 31; i >= 0; --i) sm[i + 32] = pk[i]; /* compute R */ ge25519_scalarmult_base(R, nonce); ge25519_tobytes(sm, R); /* calculate hram = H(r, a, m) */ crypto_hash_sha512(hram, sm, n + 64); sc25519_reduce(hram); /* compute S */ sc25519_muladd(sm + 32, hram, sk, nonce); /* cleanup */ cleanup(nonce); cleanup(hram); cleanup(sk); cleanup(pk); cleanup(R); return 0; }
int crypto_sign_ed25519_tinynacl_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long n, const unsigned char *pk) { long long i; unsigned char pkcopy[32], rcopy[32], scopy[32], hram[64], rcheck[32]; ge25519 R, S, A; int ret = -1; /* check input */ if (n < 64) goto fail; if (sm[63] & 224) goto fail; /* unpack pk */ if (ge25519_frombytes_negate_vartime(A, pk) != 0) goto fail; /* copy pk, r, s */ for (i = 0; i < 32; ++i) pkcopy[i] = pk[i]; for (i = 0; i < 32; ++i) rcopy[i] = sm[i]; for (i = 0; i < 32; ++i) scopy[i] = sm[i + 32]; /* copy sm to m and copy pk to m */ for (i = n - 1; i >= 0; --i) m[i] = sm[i]; for (i = 0; i < 32; ++i) m[i + 32] = pkcopy[i]; /* calculate hram = H(r, a, m) */ crypto_hash_sha512(hram, m, n); sc25519_reduce(hram); /* compute R */ ge25519_scalarmult(A, A, hram); ge25519_scalarmult_base(S, scopy); ge25519_add(R, S, A); /* check R */ ge25519_tobytes(rcheck, R); if (crypto_verify_32(rcheck, rcopy) != 0) goto fail; /* copy message */ n -= 64; *mlen = n; for (i = 0; i < n; ++i) m[i] = m[i + 64]; for (i = 0; i < 64; ++i) m[i + n] = 0; ret = 0; goto cleanup; fail: for (i = 0; i < n; ++i) m[i] = 0; cleanup: cleanup(pkcopy); cleanup(rcopy); cleanup(scopy); cleanup(hram); cleanup(rcheck); cleanup(R); cleanup(S); cleanup(A); return ret; }