summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNagi5Yeq <nagi5yeq@gmail.com>2019-07-05 15:48:54 +0800
committerNagi5Yeq <nagi5yeq@gmail.com>2019-07-05 15:48:54 +0800
commit04a6585110e764c50502104e82fae9f38a2600d3 (patch)
treed934e3296ac082dc2878ab0a4ba3c063e4f362ab
parent238c2e06b0ccef3df763fb6191ba2bf01857b1dc (diff)
add detached sign, shorten the name
-rw-r--r--.gitignore3
-rw-r--r--Makefile32
-rw-r--r--defs.h2
-rw-r--r--ed448.c87
-rw-r--r--fe448.c4
-rw-r--r--fe448.h34
-rw-r--r--ge448.h14
-rw-r--r--sc448.h24
-rw-r--r--t/testv.c131
9 files changed, 274 insertions, 57 deletions
diff --git a/.gitignore b/.gitignore
index 88b3a2b..199ef58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
*.py
.vscode/
*.out
-t/
+temp/
+*.a
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3ca3a4d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,32 @@
+CFLAGS=-O2 -Wall -Wno-unused-result
+
+all: libfe448.a
+
+.PHONY: test
+test: defs.h fe448.h ge448.h sc448.h sha3.h libfe448.a
+ $(CC) $(CFLAGS) -I. t/testv.c libfe448.a -o test.out
+ ./test.out
+
+fe448.o: defs.h fe448.h
+
+sc448.o: defs.h sc448.h sha3.h
+
+ge448.o: defs.h fe448.h ge448.h sc448.h
+
+ed448.o: defs.h fe448.h ge448.h sc448.h sha3.h
+
+sha3.o: defs.h sha3.h
+
+libfe448.a: fe448.o sc448.o ge448.o ed448.o sha3.o
+ $(AR) rcs libfe448.a fe448.o sc448.o ge448.o ed448.o sha3.o
+
+ge448_gen.o: defs.h fe448.h sc448.h
+
+.PHONY: data
+data: ge448_gen.o fe448.o sc448.o
+ $(CC) $(CFLAGS) -o gen_data.out ge448_gen.o fe448.o sc448.o
+ ./gen_data.out > ge448_base.data
+
+.PHONY: clean
+clean:
+ rm *.o *.out *.a
diff --git a/defs.h b/defs.h
index 40c6fae..22f0cb2 100644
--- a/defs.h
+++ b/defs.h
@@ -13,4 +13,6 @@ typedef uint32_t crypto_uint32;
int crypto_sign_ed448_keypair(unsigned char *pk, unsigned char *sk);
+int crypto_sign_ed448_detached(unsigned char *sign, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen, const unsigned char *sk);
+
#endif /* DEFS_H */
diff --git a/ed448.c b/ed448.c
index 63a0dd6..96c78a9 100644
--- a/ed448.c
+++ b/ed448.c
@@ -5,27 +5,80 @@
/* temporarily use getrandom() */
#include <sys/random.h>
-/* sk and pk are both 57 bytes, sk is not followed by pk */
+/* Ed448, no prehash or context */
+const static unsigned char ed448_dom4[10] = {'S', 'i', 'g', 'E', 'd', '4', '4', '8', 0, 0};
+
+/* pk is 57 bytes, sk is 114 bytes, sk is followed by pk */
int crypto_sign_ed448_keypair(
unsigned char *pk,
unsigned char *sk)
{
- sc448 scsk;
- ge448 gepk;
- unsigned char extsk[114];
- sha3_ctx_t ctx;
+ int i;
+ sc448 scsk;
+ ge448 gepk;
+ unsigned char extsk[114];
+ sha3_ctx_t ctx;
+
+ (void)getrandom(sk, 57, 0);
+ shake256_init(&ctx);
+ shake_update(&ctx, sk, 57);
+ shake_xof(&ctx);
+ shake_out(&ctx, extsk, 114);
+ extsk[56] = 0;
+ extsk[55] |= 0x80;
+ extsk[0] &= 0xFC;
- (void)getrandom(sk, 57, 0);
- shake256_init(&ctx);
- shake_update(&ctx, sk, 57);
- shake_xof(&ctx);
- shake_out(&ctx, extsk, 114);
- extsk[56] = 0;
- extsk[55] |= 0x80;
- extsk[0] &= 0xFC;
+ sc448_from57bytes(&scsk, extsk);
+ ge448_scalarmult_base(&gepk, &scsk);
+ ge448_pack(pk, &gepk);
+ for (i = 0; i < 57; i++)
+ sk[57 + i] = pk[i];
+ return 0;
+}
+
+/* detached method, sign is 114 bytes */
+int crypto_sign_ed448_detached(
+ unsigned char *sign, unsigned long long *smlen,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ sc448 scsk, scr, sck;
+ ge448 ger;
+ unsigned char extsk[114];
+ unsigned char hashr[114];
+ sha3_ctx_t ctx;
- sc448_from57bytes(&scsk, extsk);
- ge448_scalarmult_base(&gepk, &scsk);
- ge448_pack(pk, &gepk);
- return 0;
+ if (smlen != NULL)
+ {
+ *smlen = 114;
+ }
+ shake256_init(&ctx);
+ shake_update(&ctx, sk, 57);
+ shake_xof(&ctx);
+ shake_out(&ctx, extsk, 114);
+ extsk[56] = 0;
+ extsk[55] |= 0x80;
+ extsk[0] &= 0xFC;
+ shake256_init(&ctx);
+ shake_update(&ctx, ed448_dom4, 10);
+ shake_update(&ctx, extsk + 57, 57);
+ shake_update(&ctx, m, mlen);
+ shake_xof(&ctx);
+ shake_out(&ctx, hashr, 114);
+ sc448_from114bytes(&scr, hashr);
+ ge448_scalarmult_base(&ger, &scr);
+ ge448_pack(sign, &ger); /* part1: R=r[B] */
+ shake256_init(&ctx);
+ shake_update(&ctx, ed448_dom4, 10);
+ shake_update(&ctx, sign, 57);
+ shake_update(&ctx, sk + 57, 57);
+ shake_update(&ctx, m, mlen);
+ shake_xof(&ctx);
+ shake_out(&ctx, hashr, 114);
+ sc448_from114bytes(&sck, hashr);
+ sc448_from57bytes(&scsk, extsk);
+ sc448_mul(&scsk, &scsk, &sck);
+ sc448_add(&scsk, &scsk, &scr);
+ sc448_to57bytes(sign + 57, &scsk); /* part2: S=r+s*k */
+ return 0;
}
diff --git a/fe448.c b/fe448.c
index b0c413d..5994eb4 100644
--- a/fe448.c
+++ b/fe448.c
@@ -1,6 +1,3 @@
-#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
-#define WINDOWMASK ((1 << WINDOWSIZE) - 1)
-
#include "fe448.h"
/* 2**448-2**224-1 */
@@ -36,6 +33,7 @@ static void reduce_add_sub(fe448 *r)
crypto_uint32 t;
int i, rep;
+ /* not sure for the rep */
for (rep = 0; rep < 4; rep++)
{
t = r->v[56];
diff --git a/fe448.h b/fe448.h
index 535eeb5..2580d47 100644
--- a/fe448.h
+++ b/fe448.h
@@ -3,23 +3,23 @@
#include "defs.h"
-#define fe448 crypto_sign_ed448_ref_fe448
-#define fe448_freeze crypto_sign_ed448_ref_fe448_freeze
-#define fe448_unpack crypto_sign_ed448_ref_fe448_unpack
-#define fe448_pack crypto_sign_ed448_ref_fe448_pack
-#define fe448_iszero crypto_sign_ed448_ref_fe448_iszero
-#define fe448_iseq_vartime crypto_sign_ed448_ref_fe448_iseq_vartime
-#define fe448_cmov crypto_sign_ed448_ref_fe448_cmov
-#define fe448_setone crypto_sign_ed448_ref_fe448_setone
-#define fe448_setzero crypto_sign_ed448_ref_fe448_setzero
-#define fe448_neg crypto_sign_ed448_ref_fe448_neg
-#define fe448_getparity crypto_sign_ed448_ref_fe448_getparity
-#define fe448_add crypto_sign_ed448_ref_fe448_add
-#define fe448_sub crypto_sign_ed448_ref_fe448_sub
-#define fe448_mul crypto_sign_ed448_ref_fe448_mul
-#define fe448_square crypto_sign_ed448_ref_fe448_square
-#define fe448_invert crypto_sign_ed448_ref_fe448_invert
-#define fe448_pow446 crypto_sign_ed448_ref_fe448_pow446
+#define fe448 crypto_sign_fe448
+#define fe448_freeze crypto_sign_fe448_freeze
+#define fe448_unpack crypto_sign_fe448_unpack
+#define fe448_pack crypto_sign_fe448_pack
+#define fe448_iszero crypto_sign_fe448_iszero
+#define fe448_iseq_vartime crypto_sign_fe448_iseq_vartime
+#define fe448_cmov crypto_sign_fe448_cmov
+#define fe448_setone crypto_sign_fe448_setone
+#define fe448_setzero crypto_sign_fe448_setzero
+#define fe448_neg crypto_sign_fe448_neg
+#define fe448_getparity crypto_sign_fe448_getparity
+#define fe448_add crypto_sign_fe448_add
+#define fe448_sub crypto_sign_fe448_sub
+#define fe448_mul crypto_sign_fe448_mul
+#define fe448_square crypto_sign_fe448_square
+#define fe448_invert crypto_sign_fe448_invert
+#define fe448_pow446 crypto_sign_fe448_pow446
typedef struct
{
diff --git a/ge448.h b/ge448.h
index dbdfccf..5e4ce5c 100644
--- a/ge448.h
+++ b/ge448.h
@@ -4,13 +4,13 @@
#include "fe448.h"
#include "sc448.h"
-#define ge448 crypto_sign_ed448_ref_ge448
-#define ge448_base crypto_sign_ed448_ref_ge448_base
-#define ge448_unpackneg_vartime crypto_sign_ed448_ref_unpackneg_vartime
-#define ge448_pack crypto_sign_ed448_ref_pack
-#define ge448_isneutral_vartime crypto_sign_ed448_ref_isneutral_vartime
-#define ge448_double_scalarmult_vartime crypto_sign_ed448_ref_double_scalarmult_vartime
-#define ge448_scalarmult_base crypto_sign_ed448_ref_scalarmult_base
+#define ge448 crypto_sign_ge448
+#define ge448_base crypto_sign_ge448_base
+#define ge448_unpackneg_vartime crypto_sign_unpackneg_vartime
+#define ge448_pack crypto_sign_pack
+#define ge448_isneutral_vartime crypto_sign_isneutral_vartime
+#define ge448_double_scalarmult_vartime crypto_sign_double_scalarmult_vartime
+#define ge448_scalarmult_base crypto_sign_scalarmult_base
typedef struct
{
diff --git a/sc448.h b/sc448.h
index 16152a5..da3b10a 100644
--- a/sc448.h
+++ b/sc448.h
@@ -3,18 +3,18 @@
#include "defs.h"
-#define sc448 crypto_sign_ed448_ref_sc448
-#define sc448_from57bytes crypto_sign_ed448_ref_sc448_from57bytes
-#define sc448_from114bytes crypto_sign_ed448_ref_sc448_from114bytes
-#define sc448_to57bytes crypto_sign_ed448_ref_sc448_to57bytes
-#define sc448_iszero_vartime crypto_sign_ed448_ref_sc448_iszero_vartime
-#define sc448_isshort_vartime crypto_sign_ed448_ref_sc448_isshort_vartime
-#define sc448_lt_vartime crypto_sign_ed448_ref_sc448_lt_vartime
-#define sc448_add crypto_sign_ed448_ref_sc448_add
-#define sc448_sub_nored crypto_sign_ed448_ref_sc448_sub_nored
-#define sc448_mul crypto_sign_ed448_ref_sc448_mul
-#define sc448_window3 crypto_sign_ed448_ref_sc448_window3
-#define sc448_2interleave2 crypto_sign_ed448_ref_sc448_2interleave2
+#define sc448 crypto_sign_sc448
+#define sc448_from57bytes crypto_sign_sc448_from57bytes
+#define sc448_from114bytes crypto_sign_sc448_from114bytes
+#define sc448_to57bytes crypto_sign_sc448_to57bytes
+#define sc448_iszero_vartime crypto_sign_sc448_iszero_vartime
+#define sc448_isshort_vartime crypto_sign_sc448_isshort_vartime
+#define sc448_lt_vartime crypto_sign_sc448_lt_vartime
+#define sc448_add crypto_sign_sc448_add
+#define sc448_sub_nored crypto_sign_sc448_sub_nored
+#define sc448_mul crypto_sign_sc448_mul
+#define sc448_window3 crypto_sign_sc448_window3
+#define sc448_2interleave2 crypto_sign_sc448_2interleave2
typedef struct
{
diff --git a/t/testv.c b/t/testv.c
new file mode 100644
index 0000000..6122371
--- /dev/null
+++ b/t/testv.c
@@ -0,0 +1,131 @@
+#include "defs.h"
+#include <stdio.h>
+#include <assert.h>
+
+void bin2hex(unsigned char *out, const char *in)
+{
+ char t;
+ const char *p = in;
+ unsigned char x;
+
+ while (*p != '\0')
+ {
+ if (*p >= '0' && *p <= '9')
+ {
+ t = *p - '0';
+ }
+ else if (*p >= 'a' && *p <= 'z')
+ {
+ t = *p - 'a' + 10;
+ }
+ else
+ {
+ t = *p - 'A' + 10;
+ }
+ x = t << 4;
+ p++;
+ if (*p >= '0' && *p <= '9')
+ {
+ t = *p - '0';
+ }
+ else if (*p >= 'a' && *p <= 'z')
+ {
+ t = *p - 'a' + 10;
+ }
+ else
+ {
+ t = *p - 'A' + 10;
+ }
+ x += t;
+ *out++ = x;
+ p++;
+ }
+}
+
+typedef struct
+{
+ const char *sk;
+ const char *pk;
+ const char *sign;
+ const unsigned char *msg;
+ unsigned long long mlen;
+} test_t;
+
+/* check sign, pk can't be NULL */
+void testsign(const test_t *tests, int ntest)
+{
+ int i, j;
+ unsigned char bsk[114];
+ unsigned char bsign[114];
+ unsigned char mysign[114];
+ for (j = 0; j < ntest; j++)
+ {
+ bin2hex(bsk, tests[j].sk);
+ bin2hex(bsk + 57, tests[j].pk);
+ bin2hex(bsign, tests[j].sign);
+ crypto_sign_ed448_detached(mysign, NULL, tests[j].msg, tests[j].mlen, bsk);
+ for (i = 0; i < 114; i++)
+ {
+ assert(bsign[i] == mysign[i]);
+ }
+ printf("test %d good\n", j);
+ }
+}
+
+/* test vectors from rfc8032 */
+const test_t tests[] = {
+ {"6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b",
+ "5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180",
+ "533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980"
+ "ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600",
+ NULL, 0},
+ {"c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e",
+ "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480",
+ "26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f4352541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd77980"
+ "5e0dbcc0aae1cbcee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0ff3348ab21aa4adafd1d234441cf807c03a00",
+ (unsigned char *)"\x03", 1},
+ {"cd23d24f714274e744343237b93290f511f6425f98e64459ff203e8985083ffdf60500553abc0e05cd02184bdb89c4ccd67e187951267eb328",
+ "dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400",
+ "1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d389dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00"
+ "b8dbdeea6d3b051068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5028961c9bf8ffd973fe5d5c206492b140e00",
+ (unsigned char *)"\x0c\x3e\x54\x40\x74\xec\x63\xb0\x26\x5e\x0c", 11},
+ {"258cdd4ada32ed9c9ff54e63756ae582fb8fab2ac721f2c8e676a72768513d939f63dddb55609133f29adf86ec9929dccb52c1c5fd2ff7e21b",
+ "3ba16da0c6f2cc1f30187740756f5e798d6bc5fc015d7c63cc9510ee3fd44adc24d8e968b6e46e6f94d19b945361726bd75e149ef09817f580",
+ "7eeeab7c4e50fb799b418ee5e3197ff6bf15d43a14c34389b59dd1a7b1b85b4ae90438aca634bea45e3a2695f1270f07fdcdf7c62b8efeaf00"
+ "b45c2c96ba457eb1a8bf075a3db28e5c24f6b923ed4ad747c3c9e03c7079efb87cb110d3a99861e72003cbae6d6b8b827e4e6c143064ff3c00",
+ (unsigned char *)"\x64\xa6\x5f\x3c\xde\xdc\xdd\x66\x81\x1e\x29\x15", 12},
+ {"7ef4e84544236752fbb56b8f31a23a10e42814f5f55ca037cdcc11c64c9a3b2949c1bb60700314611732a6c2fea98eebc0266a11a93970100e",
+ "b3da079b0aa493a5772029f0467baebee5a8112d9d3a22532361da294f7bb3815c5dc59e176b4d9f381ca0938e13c6c07b174be65dfa578e80",
+ "6a12066f55331b6c22acd5d5bfc5d71228fbda80ae8dec26bdd306743c5027cb4890810c162c027468675ecf645a83176c0d7323a2ccde2d80"
+ "efe5a1268e8aca1d6fbc194d3f77c44986eb4ab4177919ad8bec33eb47bbb5fc6e28196fd1caf56b4e7e0ba5519234d047155ac727a1053100",
+ (unsigned char *)"\x64\xa6\x5f\x3c\xde\xdc\xdd\x66\x81\x1e\x29\x15\xe7", 13},
+ {"d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bff21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01",
+ "df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00",
+ "554bc2480860b49eab8532d2a533b7d578ef473eeb58c98bb2d0e1ce488a98b18dfde9b9b90775e67f47d4a1c3482058efc9f40d2ca033a080"
+ "1b63d45b3b722ef552bad3b4ccb667da350192b61c508cf7b6b5adadc2c8d9a446ef003fb05cba5f30e88e36ec2703b349ca229c2670833900",
+ (unsigned char *)"\xbd\x0f\x6a\x37\x47\xcd\x56\x1b\xdd\xdf\x46\x40\xa3\x32\x46\x1a\x4a\x30\xa1\x2a\x43\x4c\xd0\xbf"
+ "\x40\xd7\x66\xd9\xc6\xd4\x58\xe5\x51\x22\x04\xa3\x0c\x17\xd1\xf5\x0b\x50\x79\x63\x1f\x64\xeb\x31"
+ "\x12\x18\x2d\xa3\x00\x58\x35\x46\x11\x13\x71\x8d\x1a\x5e\xf9\x44",
+ 64},
+ {"2ec5fe3c17045abdb136a5e6a913e32ab75ae68b53d2fc149b77e504132d37569b7e766ba74a19bd6162343a21c8590aa9cebca9014c636df5",
+ "79756f014dcfe2079f5dd9e718be4171e2ef2486a08f25186f6bff43a9936b9bfe12402b08ae65798a3d81e22e9ec80e7690862ef3d4ed3a00",
+ "c650ddbb0601c19ca11439e1640dd931f43c518ea5bea70d3dcde5f4191fe53f00cf966546b72bcc7d58be2b9badef28743954e3a44a23f880"
+ "e8d4f1cfce2d7a61452d26da05896f0a50da66a239a8a188b6d825b3305ad77b73fbac0836ecc60987fd08527c1a8e80d5823e65cafe2a3d00",
+ (unsigned char *)"\x15\x77\x75\x32\xb0\xbd\xd0\xd1\x38\x9f\x63\x6c\x5f\x6b\x9b\xa7\x34\xc9\x0a\xf5\x72\x87\x7e\x2d"
+ "\x27\x2d\xd0\x78\xaa\x1e\x56\x7c\xfa\x80\xe1\x29\x28\xbb\x54\x23\x30\xe8\x40\x9f\x31\x74\x50\x41"
+ "\x07\xec\xd5\xef\xac\x61\xae\x75\x04\xda\xbe\x2a\x60\x2e\xde\x89\xe5\xcc\xa6\x25\x7a\x7c\x77\xe2"
+ "\x7a\x70\x2b\x3a\xe3\x9f\xc7\x69\xfc\x54\xf2\x39\x5a\xe6\xa1\x17\x8c\xab\x47\x38\xe5\x43\x07\x2f"
+ "\xc1\xc1\x77\xfe\x71\xe9\x2e\x25\xbf\x03\xe4\xec\xb7\x2f\x47\xb6\x4d\x04\x65\xaa\xea\x4c\x7f\xad"
+ "\x37\x25\x36\xc8\xba\x51\x6a\x60\x39\xc3\xc2\xa3\x9f\x0e\x4d\x83\x2b\xe4\x32\xdf\xa9\xa7\x06\xa6"
+ "\xe5\xc7\xe1\x9f\x39\x79\x64\xca\x42\x58\x00\x2f\x7c\x05\x41\xb5\x90\x31\x6d\xbc\x56\x22\xb6\xb2"
+ "\xa6\xfe\x7a\x4a\xbf\xfd\x96\x10\x5e\xca\x76\xea\x7b\x98\x81\x6a\xf0\x74\x8c\x10\xdf\x04\x8c\xe0"
+ "\x12\xd9\x01\x01\x5a\x51\xf1\x89\xf3\x88\x81\x45\xc0\x36\x50\xaa\x23\xce\x89\x4c\x3b\xd8\x89\xe0"
+ "\x30\xd5\x65\x07\x1c\x59\xf4\x09\xa9\x98\x1b\x51\x87\x8f\xd6\xfc\x11\x06\x24\xdc\xbc\xde\x0b\xf7"
+ "\xa6\x9c\xcc\xe3\x8f\xab\xdf\x86\xf3\xbe\xf6\x04\x48\x19\xde\x11",
+ 256}};
+
+int main()
+{
+ testsign(tests, 7);
+ return 0;
+}