Verifiable Random Function implementation in Javascript [closed]

I’m trying to implement the VRF in JavaScript as described in this paper https://tools.ietf.org/pdf/draft-irtf-cfrg-vrf-06.pdf .
I use ed25519 from the elliptic.js library and the bn.js library for big integer
The ‘ecvrf_prove’ and ‘ecvrf_prove_to_hash’ function already work, but the ‘ecvrf_verify’ function can’t verify the proof.
My first idea was to look at the calculation of U and V in steps 5 and 6. But i didn’t find any error or maybe i didn’t understand the whole thing.
Here is some code, maybe can someone can help me fix this or tell me what i’m doing wrong.
Thanks

// 5.3. ECVRF Verifying
/**
 * ECVRF_verify(Y, pi_string, alpha_string)
 * @param {*} y public key, an EC point
 * @param {*} pi_string  VRF proof, octet string of length ptLen+n+qLen
 * @param {*} alpha_string VRF input, octet string
 * @return ("VALID", beta_string), where beta_string is the VRF hash output, octet string
        of length hLen (64) bytes; or ("INVALID", []) upon failure
 */
function ecvrf_verify(y, pi_string, alpha_string) {
    // 1. D = ECVRF_decode_proof(pi_string)
    // 2. If D is "INVALID", output "INVALID" and stop
    const d = _ecvrf_decode_proof(pi_string)
    if (d == 'INVALID') {
        return 'INVALID'
    }

    // 3. (Gamma, c, s) = D
    const gamma = d[0]
    const c = d[1]
    const s = d[2]

    // 4. H = ECVRF_hash_to_curve(suite_string, y, alpha_string)
    const y_point = _string_to_point(y)
    if (y_point == 'INVALID') {
        return 'INVALID'
    }

    const h = _ecvrf_hash_to_try_and_increment(SUITE_STRING, y_point, alpha_string)
    if (h == 'INVALID') {
        return 'INVALID'
    }

    // 5. U = s*B - c*y
    const s_b = BASE.mul(s)
    let c_y = y_point.mul(c)
    // Negate c_y
    c_y = c_y.neg()
    const u = s_b.add(c_y)

    // 6. V = s*H - c*Gamma
    const s_h = h.mul(s)
    let c_g = gamma.mul(s)
    // Negate c_g
    c_g = c_g.neg()
    const v = s_h.add(c_g)

    // 7. c’ = ECVRF_hash_points(H, Gamma, U, V)
    const cp = _ecvrf_hash_points(h, gamma, u, v)

    // 8. If c and c’ are equal, output ("VALID", ECVRF_proof_to_hash(pi_string)); else output "INVALID"
    if (c.eq(cp)) {
        return {
            status: 'VALID',
            pi_string: ecvrf_proof_to_hash(pi_string)
        }
    }
    else{
        return 'INVALID'
    }
}
// section 5.4.3. ECVRF Hash Points
/**
 * ECVRF_hash_points(P1, P2, ..., PM)
 * @param {*} p1 an EC points in G
 * @param {*} p2 an EC points in G
 * @param {*} p3 an EC points in G
 * @param {*} p4 an EC points in G
 * @retrun c hash value, integer between 0 and 2^(8n)-1
 */
function _ecvrf_hash_points(p1, p2, p3, p4) {
    // 1. two_string = 0x02 = int_to_string(2, 1), a single octet with value 2
    const two_string = Buffer.alloc(1, 2)

    // 2. Initialize str = suite_string || two_string
    let string = Buffer.concat([SUITE_STRING, two_string])

    // 3.for PJ in [P1, P2, ... PM]:
    //       str = str || point_to_string(PJ)
    string = Buffer.concat([string, _point_to_string(p1), _point_to_string(p2), _point_to_string(p3), _point_to_string(p4)])

    // 4. c_string = Hash(str)
    const c_string = _hash(string)

    // 5. truncated_c_string = c_string[0]...c_string[n-1]
    const truncated_c_string = c_string.slice(0, 16)

    // 6. c = string_to_int(truncated_c_string)
   const c = _string_to_int(truncated_c_string)

    // 7. Output c
    return c
}