summaryrefslogtreecommitdiff
path: root/src/libsodium/crypto_sign/ed25519/ref10/sign.c
diff options
context:
space:
mode:
authorMicah Anderson <micah@riseup.net>2014-08-11 13:49:21 -0400
committerMicah Anderson <micah@riseup.net>2014-08-11 13:49:21 -0400
commit2e59f9740a29439df7c7a56cf0ae83dec3081d31 (patch)
treed5e7c4e74c9a0f1ea999327d2e68b1dd27be00e0 /src/libsodium/crypto_sign/ed25519/ref10/sign.c
initial import of debian version from mentors0.6.1
Diffstat (limited to 'src/libsodium/crypto_sign/ed25519/ref10/sign.c')
-rw-r--r--src/libsodium/crypto_sign/ed25519/ref10/sign.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/libsodium/crypto_sign/ed25519/ref10/sign.c b/src/libsodium/crypto_sign/ed25519/ref10/sign.c
new file mode 100644
index 0000000..88f4710
--- /dev/null
+++ b/src/libsodium/crypto_sign/ed25519/ref10/sign.c
@@ -0,0 +1,71 @@
+
+#include <string.h>
+
+#include "api.h"
+#include "crypto_hash_sha512.h"
+#include "ge.h"
+#include "sc.h"
+
+int
+crypto_sign_detached(unsigned char *sig, unsigned long long *siglen,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ crypto_hash_sha512_state hs;
+ unsigned char pk[32];
+ unsigned char az[64];
+ unsigned char nonce[64];
+ unsigned char hram[64];
+ ge_p3 R;
+
+ memmove(pk, sk + 32, 32);
+
+ crypto_hash_sha512(az, sk, 32);
+ az[0] &= 248;
+ az[31] &= 63;
+ az[31] |= 64;
+
+ crypto_hash_sha512_init(&hs);
+ crypto_hash_sha512_update(&hs, az + 32, 32);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, nonce);
+
+ memmove(sig + 32, pk, 32);
+
+ sc_reduce(nonce);
+ ge_scalarmult_base(&R, nonce);
+ ge_p3_tobytes(sig, &R);
+
+ crypto_hash_sha512_init(&hs);
+ crypto_hash_sha512_update(&hs, sig, 64);
+ crypto_hash_sha512_update(&hs, m, mlen);
+ crypto_hash_sha512_final(&hs, hram);
+
+ sc_reduce(hram);
+ sc_muladd(sig + 32, hram, az, nonce);
+
+ if (siglen != NULL) {
+ *siglen = 64U;
+ }
+ return 0;
+}
+
+int
+crypto_sign(unsigned char *sm, unsigned long long *smlen,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ unsigned long long siglen;
+
+ if (crypto_sign_detached(sm, &siglen, m, mlen, sk) != 0 ||
+ siglen > crypto_sign_ed25519_BYTES) {
+ *smlen = 0;
+ memset(sm, 0, mlen + crypto_sign_ed25519_BYTES);
+ return -1;
+ }
+ memmove(sm + siglen, m, mlen);
+ if (smlen != NULL) {
+ *smlen = mlen + siglen;
+ }
+ return 0;
+}