Line data Source code
1 : /* Instantiate ECDSA verification for a prime curve. */
2 :
3 : #ifndef PCURVE_NAME
4 : #error "Define PCURVE_NAME"
5 : #endif
6 : #ifndef PCURVE_SCALAR_SZ
7 : #error "Define PCURVE_SCALAR_SZ"
8 : #endif
9 : #ifndef PCURVE_SCALAR_T
10 : #error "Define PCURVE_SCALAR_T"
11 : #endif
12 : #ifndef PCURVE_POINT_T
13 : #error "Define PCURVE_POINT_T"
14 : #endif
15 : #ifndef PCURVE_SHA_NAME
16 : #error "Define PCURVE_SHA_NAME"
17 : #endif
18 : #ifndef PCURVE_SHA_T
19 : #error "Define PCURVE_SHA_T"
20 : #endif
21 : #ifndef PCURVE_SHA_SZ
22 : #error "Define PCURVE_SHA_SZ"
23 : #endif
24 : #ifndef PCURVE_SUCCESS
25 : #error "Define PCURVE_SUCCESS"
26 : #endif
27 : #ifndef PCURVE_FAILURE
28 : #error "Define PCURVE_FAILURE"
29 : #endif
30 :
31 34770 : #define PCURVE_(x) FD_EXPAND_THEN_CONCAT3(PCURVE_NAME,_,x)
32 14895 : #define SHA_(x) FD_EXPAND_THEN_CONCAT3(PCURVE_SHA_NAME,_,x)
33 :
34 : int
35 : PCURVE_(public_key_compress)( uchar compressed[ 1+PCURVE_SCALAR_SZ ],
36 4443 : uchar const uncompressed[ 1+2*PCURVE_SCALAR_SZ ] ) {
37 4443 : if( FD_UNLIKELY( !PCURVE_(point_validate_uncompressed)( uncompressed ) ) ) return PCURVE_FAILURE;
38 :
39 4404 : compressed[ 0 ] = (uchar)( 0x02U | ( uncompressed[ 2*PCURVE_SCALAR_SZ ] & 0x01U ) );
40 4404 : fd_memcpy( compressed+1, uncompressed+1, PCURVE_SCALAR_SZ );
41 4404 : return PCURVE_SUCCESS;
42 4443 : }
43 :
44 : static int
45 : PCURVE_(verify_impl)( uchar const msg[],
46 : ulong msg_sz,
47 : uchar const sig[ 2*PCURVE_SCALAR_SZ ],
48 : uchar const public_key[ 1+PCURVE_SCALAR_SZ ],
49 : PCURVE_SHA_T * sha,
50 4980 : int low_s ) {
51 4980 : PCURVE_SCALAR_T r[1], s[1], u1[1], u2[1];
52 4980 : PCURVE_POINT_T public[1], point[1];
53 :
54 4980 : if( FD_UNLIKELY( !PCURVE_(scalar_frombytes)( r, sig ) ) ) return PCURVE_FAILURE;
55 4977 : if( FD_UNLIKELY( !( low_s ? PCURVE_(scalar_frombytes_positive)( s, sig+PCURVE_SCALAR_SZ )
56 4977 : : PCURVE_(scalar_frombytes) ( s, sig+PCURVE_SCALAR_SZ ) ) ) ) return PCURVE_FAILURE;
57 4974 : if( FD_UNLIKELY( PCURVE_(scalar_is_zero)( r ) | PCURVE_(scalar_is_zero)( s ) ) ) return PCURVE_FAILURE;
58 4965 : if( FD_UNLIKELY( !PCURVE_(point_frombytes)( public, public_key ) ) ) return PCURVE_FAILURE;
59 :
60 4965 : uchar hash[ PCURVE_SHA_SZ ];
61 4965 : SHA_(fini)( SHA_(append)( SHA_(init)( sha ), msg, msg_sz ), hash );
62 4965 : PCURVE_(scalar_from_digest)( u1, hash );
63 :
64 4965 : PCURVE_(scalar_inv)( s, s );
65 4965 : PCURVE_(scalar_mul)( u1, u1, s );
66 4965 : PCURVE_(scalar_mul)( u2, r, s );
67 4965 : PCURVE_(double_scalar_mul_base)( point, u1, public, u2 );
68 4965 : return PCURVE_(point_eq_x)( point, r ) ? PCURVE_SUCCESS : PCURVE_FAILURE;
69 4965 : }
70 :
71 : int
72 : PCURVE_(verify)( uchar const msg[],
73 : ulong msg_sz,
74 : uchar const sig[ 2*PCURVE_SCALAR_SZ ],
75 : uchar const public_key[ 1+PCURVE_SCALAR_SZ ],
76 3024 : PCURVE_SHA_T * sha ) {
77 3024 : return PCURVE_(verify_impl)( msg, msg_sz, sig, public_key, sha, 1 );
78 3024 : }
79 :
80 : int
81 : PCURVE_(verify_allow_high_s)( uchar const msg[],
82 : ulong msg_sz,
83 : uchar const sig[ 2*PCURVE_SCALAR_SZ ],
84 : uchar const public_key[ 1+PCURVE_SCALAR_SZ ],
85 1956 : PCURVE_SHA_T * sha ) {
86 1956 : return PCURVE_(verify_impl)( msg, msg_sz, sig, public_key, sha, 0 );
87 1956 : }
88 :
89 : #undef PCURVE_
90 : #undef SHA_
91 : #undef PCURVE_NAME
92 : #undef PCURVE_SCALAR_SZ
93 : #undef PCURVE_SCALAR_T
94 : #undef PCURVE_POINT_T
95 : #undef PCURVE_SHA_NAME
96 : #undef PCURVE_SHA_T
97 : #undef PCURVE_SHA_SZ
98 : #undef PCURVE_SUCCESS
99 : #undef PCURVE_FAILURE
|