The VXEdDSA signing algorithm takes the same inputs as XEdDSA. The output is a pair of values. First, a signature (V || h || s), which is a byte sequence of length 3b bits, where V encodes a point and h and s encode integers modulo q. Second, a VRF output byte sequence v of length equal to b bits, formed by multiplying the V output by the cofactor c.
The VXEdDSA verification algorithm takes the same inputs as XEdDSA, except with a VXEdDSA signature instead of an XEdDSA signature. If VXEdDSA verification is successful, it returns a VRF output byte sequence v of length equal to b bits; otherwise it returns false.
Below is the pseudocode for the vxeddsa_sign and vxeddsa_verify functions.
vxeddsa_sign(k, M, Z):
A, a = calculate_key_pair(k)
B_v = hash_to_point(A || M)
V = aB_v
r = hash_3(a || V || Z) (mod q)
R = rB
R_v = rB_v
h = hash_4(A || V || R || R_v || M) (mod q)
s = r + ha (mod q)
v = hash_5(cV) (mod 2^b)
return (V || h || s), v
vxeddsa_verify(u, M, (V || h || s)):
if u >= p or V.y >= 2^|p| or h >= 2^|q| or s >= 2^|q|:
return false
A = convert_mont(u)
B_v = hash_to_point(A || M)
if not on_curve(A) or not on_curve(V):
return false
if cA == I or cV == I or B_v == I:
return false
R = sB - hA
R_v = sB_v - hV
h_check = hash_4(A || V || R || R_v || M) (mod q)
if bytes_equal(h, h_check):
v = hash_5(cV) (mod 2^b)
return v
return false