diff options
Diffstat (limited to 'libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c')
-rw-r--r-- | libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c new file mode 100644 index 0000000000..412f8c4c9b --- /dev/null +++ b/libs/libaxolotl/src/curve25519/ed25519/additions/uopen_modified.c @@ -0,0 +1,100 @@ +#include <string.h> +#include "sc.h" +#include "ge.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "crypto_additions.h" +#include "crypto_sign.h" + +int crypto_usign_open_modified( + unsigned char *m,unsigned long long *mlen, + const unsigned char *sm,unsigned long long smlen, + const unsigned char *pk, const ge_p3* Bu +) +{ + ge_p3 U; + unsigned char h[64]; + unsigned char s[64]; + unsigned char strict[64]; + ge_p3 A; + ge_p2 R; + unsigned char hcheck[64]; + int count; + + if (smlen < 96) goto badsig; + if (sm[63] & 224) goto badsig; /* strict parsing of h */ + if (sm[95] & 224) goto badsig; /* strict parsing of s */ + + /* Load -A */ + if (ge_frombytes_negate_vartime(&A,pk) != 0) goto badsig; + + /* Load -U, h, s */ + ge_frombytes_negate_vartime(&U, sm); + memset(h, 0, 64); + memset(s, 0, 64); + memmove(h, sm + 32, 32); + memmove(s, sm + 64, 32); + + /* Insist that s and h are reduced scalars (strict parsing) */ + memcpy(strict, h, 64); + sc_reduce(strict); + if (memcmp(strict, h, 32) != 0) + goto badsig; + memcpy(strict, s, 64); + sc_reduce(strict); + if (memcmp(strict, s, 32) != 0) + goto badsig; + + /* Reject U (actually -U) if small order */ + if (ge_is_small_order(&U)) + goto badsig; + + // R = sB + h(-A) + ge_double_scalarmult_vartime(&R,h,&A,s); + + // Ru = sBu + h(-U) + ge_p3 sBu, hU; + + // sBu + ge_scalarmult(&sBu, s, Bu); + + // h(-U) + ge_scalarmult(&hU, h, &U); + + // Ru = sBu + h(-U) + ge_p1p1 Rp1p1; + ge_p3 Ru; + ge_cached hUcached; + ge_p3_to_cached(&hUcached, &hU); + ge_add(&Rp1p1, &sBu, &hUcached); + ge_p1p1_to_p3(&Ru, &Rp1p1); + + + // Check h == SHA512(label(4) || A || U || R || Ru || M) + m[0] = 0xFB; + for (count = 1; count < 32; count++) + m[count] = 0xFF; + memmove(m+32, pk, 32); + /* undo the negation for U */ + fe_neg(U.X, U.X); + fe_neg(U.T, U.T); + ge_p3_tobytes(m+64, &U); + ge_tobytes(m+96, &R); + ge_p3_tobytes(m+128, &Ru); + memmove(m+160, sm+96, smlen - 96); + + crypto_hash_sha512(hcheck, m, smlen + 64); + sc_reduce(hcheck); + + if (crypto_verify_32(hcheck, h) == 0) { + memmove(m,m + 64,smlen - 64); + memset(m + smlen - 64,0,64); + *mlen = smlen - 64; + return 0; + } + +badsig: + *mlen = -1; + memset(m,0,smlen); + return -1; +} |