def METHOD_NAME(self, index, mpk, pk, sk, M):
    if debug: print("pk =>", pk.keys())
    (A_pk, B_pk, C_pk) = self.getPKdict(mpk, pk, ['A', 'B', 'C'])
    m = H(M)
    l = len(A_pk.keys())
    assert index >= 0 and index < l, "invalid index"
    if debug: print("l defined as =>", l)        
    s = {}
    S = {}
    for i in range(0, l):
        if i != index:
           s[i] = group.random(ZR)	
           S[i] = mpk['g1'] ** s[i]   
    t = [group.random(ZR) for i in range(l)]
    # index=0
    (A, B, C) = A_pk[ 0 ], B_pk[ 0 ], C_pk[ 0 ]
    prod = (A * (B ** m) * (C ** t[0])) ** -s[0]
    # 1 -> l
    for i in range(1, l):
        if i != index:
           (A, B, C) = A_pk[i], B_pk[i], C_pk[i]
           prod *= ((A * (B ** m) * (C ** t[i])) ** -s[i])            
    d = (sk['a'] + (sk['b'] * m) + (sk['c'] * t[index]))  # s[l]
    S[index] = (mpk['g1'] * prod) ** (1 / d) # S[l]
    if debug: print("S[", index, "] :=", S[index])
    sig = { 'S':S, 't':t }
    return sig