1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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;
ge_p1p1 Rp1p1;
ge_p3 Rv;
ge_cached h_Vnegcached;
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_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;
}
|