summaryrefslogtreecommitdiff
path: root/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 07:56:33 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-02-13 09:09:08 +0300
commit193f645f65ad4ffdec3186e4176b23af10861199 (patch)
treee1b16b48ac74c5f03f99a98798e849f6dd9752cc /libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
parent36c32a13878d3bd94e88bd9c764f1eadb05ea1ed (diff)
libs:
libaxolotl: updated libaxolotl (libsignal-c) from (https://github.com/WhisperSystems/libsignal-protocol-c)
Diffstat (limited to 'libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c')
-rw-r--r--libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
new file mode 100644
index 0000000000..3dfc7fba6f
--- /dev/null
+++ b/libs/libaxolotl/src/curve25519/ed25519/additions/vopen_modified.c
@@ -0,0 +1,85 @@
+#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_vsign_open_modified(
+ unsigned char *m,
+ const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *pk, const ge_p3* Bv
+)
+{
+ ge_p3 Vneg, V, Aneg, A, c_V, c_A, h_Vneg, s_Bv;
+ unsigned char h[32];
+ unsigned char s[32];
+ ge_p2 R;
+ unsigned char hcheck[64];
+ unsigned char vrf_output[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(&Aneg,pk) != 0) goto badsig;
+
+ /* Load -V, h, s */
+ if (ge_frombytes_negate_vartime(&Vneg, sm) != 0) goto badsig;
+ memmove(h, sm + 32, 32);
+ memmove(s, sm + 64, 32);
+ if (h[31] & 224) goto badsig; /* strict parsing of h */
+ if (s[31] & 224) goto badsig; /* strict parsing of s */
+
+ ge_neg(&A, &Aneg);
+ ge_neg(&V, &Vneg);
+ ge_scalarmult_cofactor(&c_A, &A);
+ ge_scalarmult_cofactor(&c_V, &V);
+ if (ge_isneutral(&c_A) || ge_isneutral(&c_V) || ge_isneutral(Bv))
+ goto badsig;
+
+ // R = (s*B) + (h * -A))
+ ge_double_scalarmult_vartime(&R, h, &Aneg, s);
+
+ // s * Bv
+ ge_scalarmult(&s_Bv, s, Bv);
+
+ // h * -V
+ ge_scalarmult(&h_Vneg, h, &Vneg);
+
+ // Rv = (sc * Bv) + (hc * (-V))
+ ge_p1p1 Rp1p1;
+ ge_p3 Rv;
+ ge_cached h_Vnegcached;
+ ge_p3_to_cached(&h_Vnegcached, &h_Vneg);
+ ge_add(&Rp1p1, &s_Bv, &h_Vnegcached);
+ ge_p1p1_to_p3(&Rv, &Rp1p1);
+
+ // Check h == SHA512(label(4) || A || V || R || Rv || M)
+ m[0] = 0xFB; // label 4
+ for (count = 1; count < 32; count++)
+ m[count] = 0xFF;
+ memmove(m+32, pk, 32);
+ ge_p3_tobytes(m+64, &V);
+ ge_tobytes(m+96, &R);
+ ge_p3_tobytes(m+128, &Rv);
+ memmove(m+160, sm+96, smlen - 96);
+
+ crypto_hash_sha512(hcheck, m, smlen + 64);
+ sc_reduce(hcheck);
+
+ if (crypto_verify_32(hcheck, h) == 0) {
+ ge_p3_tobytes(m+32, &c_V);
+ m[0] = 0xFA; // label 5
+ crypto_hash_sha512(vrf_output, m, 64);
+ memmove(m, vrf_output, 32);
+ return 0;
+ }
+
+badsig:
+ memset(m, 0, 32);
+ return -1;
+}