Example #1
0
def pedersen_prover(C, X, x, r, rnd_bytes=os.urandom, RO=sha2):
    """
    Params: 
       x and r are elements of Fp
       C,X are Points
    Returns:
       prf, of the form (KX,KC,sx,sr)
    """
    assert X == x * G
    assert C == x * G + r * H

    # TODO: fill in your code here (10 points)

    # blinding factor
    kx = uint256_from_str(rnd_bytes(32)) % order
    kr = uint256_from_str(rnd_bytes(32)) % order

    # commitment
    KX = kx * G
    KC = kx * G + kr * H

    # receive challenge from random oracle
    c = uint256_from_str(RO(ser(KX) + ser(KC)))

    # responses
    sx = Fp(kx + c * x)
    sr = Fp(kr + c * r)

    return (KX, KC, sx, sr)
Example #2
0
def schnorr_verify(X, m, sig, RO=sha2):
    assert type(X) is Point
    assert type(sig) is bytes and len(sig) is 65
    (K, s) = deser(sig[:33].hex()), uint256_from_str(sig[33:])
    c = uint256_from_str(RO(ser(K) + sha2(m).hex()))
    assert s * G == K + c * X
    return True
Example #3
0
def arith_prover(a, b, A, B, C, rnd_bytes=os.urandom, RO=sha2):
    """
    Params: 
       a and b are elements of Fp
       A, B, C are Points
    Returns:
       prf, of the form (KA,KB,KC,sa,sb)

    Must satisfy verify_proof2(A, B, C, prf)
    Must be zero-knowledge
    """
    assert a * G == A
    assert b * G == B
    assert (a * (b - 3)) * G == C

    # TODO: fill in your code here (10 points)
    ka = uint256_from_str(rnd_bytes(32)) % order
    kb = uint256_from_str(rnd_bytes(32)) % order

    KA = ka * G
    KB = kb * G
    KC = kb * A
    c = uint256_from_str(RO(ser(KA) + ser(KB) + ser(KC)))

    sa = Fp(ka + a * c)
    sb = Fp(kb + b * c)

    return (KA, KB, KC, sa, sb)
Example #4
0
def dlog_extractor(A, Adv):
    assert type(A) is Point

    ## Step 1: run the adversary to generate a proof while recording
    ## the random bits and oracle queries

    # TODO: Fill your code in here

    i = 0
    l = {}
    found = False
    found2 = False
    mapping = {}

    def RO1(s):
        assert type(s) is str
        nonlocal mapping
        if not s in mapping:
            mapping[s] = os.urandom(32)
        return mapping[s]

    def RO2(s):
        assert type(s) is str
        nonlocal mapping
        if not found2:
            mapping[s] = os.urandom(32)
        return mapping[s]

    def rand(x):
        nonlocal i, l, found
        if x == 32 and found:
            return l[i]
        elif x == 32 and not found:
            i += 1
            r = os.urandom(x)
            l[i] = r
            return r
        else:
            return os.urandom(x)

    (K1, s1) = Adv(A, rnd_bytes=rand, RO=RO1)
    found = True
    c1 = uint256_from_str(RO1(ser(K1)))
    # print("c1",c1,"\n","K1",K1)
    ## Step 2: run the adversary again, replaying the random bits,
    ## and intercepting the call to the random oracle

    # TODO: Fill your code in here (5 points)
    (K2, s2) = Adv(A, rnd_bytes=rand, RO=RO2)
    found2 = True
    c2 = uint256_from_str(RO2(ser(K2)))
    # print("c2",c2,"\n","K2",K2)

    ## Step 3: Extract a witness from the two proofs and oracle queries
    # TODO: Fill your code in here (5 points)
    return Fp(s1 - s2) / Fp(c1 - c2)
Example #5
0
def arith_test():
    # Randomly choose "a" and "b"
    a = uint256_from_str(os.urandom(32))
    b = uint256_from_str(os.urandom(32))
    A = a * G
    B = b * G
    C = (a * (b - 3)) * G

    prf = arith_prover(a, b, A, B, C)
    assert arith_verifier(A, B, C, prf)
    print("Arithmetic Relation correctness test complete!")
Example #6
0
def pedersen_vector_prover(C_arr, x_arr, r_arr, rnd_bytes=os.urandom, RO=sha2):
    """
    Params: 
       x_arr, r_arr are arrays of elements in Fp
       C_arr are arrays of Points
    Returns:
       prf, of the form (K,sx,sr) where K is points and sx and sr are points in Fp 
       Note that here you are able to prove that knowledge of n points with only communicating 1 ppints and 2 scalars.
    """

    # Make sure all commitments are correct
    for C_elem, x_elem, r_elem in zip(C_arr, x_arr, r_arr):
        assert C_elem == x_elem * G + r_elem * H

    # TODO: Your code goes here: 10 points
    # commitment
    K = C_arr[0]

    c = Fp(uint256_from_str(RO(ser(K))))
    sx = x_arr[0]
    sr = r_arr[0]
    e = c
    # responses
    for i in range(len(C_arr)):
        sx = Fp(sx + e.n * x_arr[i])
        sr = Fp(sr + e.n * r_arr[i])
        e = Fp(e * c)
        # print(e.n)
    return (K, sx, sr)
Example #7
0
def dlog_prover(A, a, rnd_bytes=os.urandom, RO=sha2):
    assert a * G == A

    # blinding factor
    k = uint256_from_str(rnd_bytes(32)) % order

    # commitment
    K = k * G

    # Invoke the random oracle to receive a challenge
    c = uint256_from_str(RO(ser(K)))

    # response
    s = Fp(k + c * 124213421)

    return (K, s)
Example #8
0
def schnorr_sign(x, m, rnd_bytes=os.urandom, RO=sha2):
    assert type(x) is bytes
    assert type(m) is str

    # TODO: Your code goes here (10 points)
    k = uint256_from_str(rnd_bytes(32)) % order

    K = k * G

    c = uint256_from_str(RO(ser(K) + sha2(m).hex()))

    x = uint256_from_str(x)

    s = Fp(k + c * x)

    return bytes.fromhex(ser(K)) + uint256_to_str(s.n)
Example #9
0
def dlog_test_extractor_harder():
    # Make a test case based on running a "picky" prover
    a = uint256_from_str(os.urandom(32))
    A = a * G

    def Adv(A, rnd_bytes, RO):
        assert A == a * G

        while True:
            # The "picky" prover loops until it is happy

            # Make a whimsical decision
            coin = rnd_bytes(1)
            if ord(coin) < 128: continue

            k = uint256_from_str(rnd_bytes(32)) % order
            K = k * G
            c = uint256_from_str(RO(ser(K)))

            # I only like challenges that end with 3 zero bits
            if c & 0b111 != 0: continue

            # OK I'm satisfied
            s = Fp(k + c * a)
            return (K, s)

    a_ = dlog_extractor(A, Adv)
    assert a == a_
    print('Extractor test complete!')
Example #10
0
def dlog_prover(A,
                a,
                k=uint256_from_str(os.urandom(32)) % order,
                rnd_bytes=os.urandom,
                RO=sha2):
    assert a * G == A

    # commitment
    K = k * G

    # Invoke the random oracle to receive a challenge
    c = uint256_from_str(RO(ser(K)))

    # response
    s = Fp(k + c * a)

    return (K, s)
Example #11
0
def range_test():
    a = random.randint(0, 64)
    # print(a)
    r = uint256_from_str(os.urandom(32)) % order
    C = a * G + r * H
    prf_tuple = range_prover(a, r, C)
    assert range_verifier(C, prf_tuple)
    print("Range test complete!")
    return True
Example #12
0
def OR_test2():
    # Try second way
    b = uint256_from_str(os.urandom(32))
    A = random_point()
    B = b * G

    prf = OR_prover(A, B, b)
    assert OR_verifier(A, B, prf)
    print("OR composition correctness 2 test complete!")
Example #13
0
def schnorr_test():
    msg = "hello"

    x = os.urandom(32)
    X = uint256_from_str(x) * G

    sig = schnorr_sign(x, msg)
    assert schnorr_verify(X, msg, sig)
    print("Schnorr Test complete!")
Example #14
0
def OR_test1():
    # Try first way
    a = uint256_from_str(os.urandom(32))
    A = a * G
    B = random_point()

    prf = OR_prover(A, B, a)
    assert OR_verifier(A, B, prf)
    print("OR composition correctness 1 test complete!")
Example #15
0
    def Adv(A, rnd_bytes, RO):
        assert A == a * G

        while True:
            # The "picky" prover loops until it is happy

            # Make a whimsical decision
            coin = rnd_bytes(1)
            if ord(coin) < 128: continue

            k = uint256_from_str(rnd_bytes(32)) % order
            K = k * G
            c = uint256_from_str(RO(ser(K)))

            # I only like challenges that end with 3 zero bits
            if c & 0b111 != 0: continue

            # OK I'm satisfied
            s = Fp(k + c * a)
            return (K, s)
Example #16
0
def dlog_verifier(A, prf, RO=sha2):
    (K, s) = prf
    assert type(A) is type(K) is Point
    assert type(s) is Fp

    # Recompute c w/ the information given
    c = uint256_from_str(RO(ser(K)))

    # Check the verification condition
    assert s.n * G == K + c * A
    return True
Example #17
0
def pedersen_verifier(C, X, prf, RO=sha2):
    (KX, KC, sx, sr) = prf
    assert type(KX) == type(KC) == Point
    assert type(sx) == type(sr) == Fp

    # Recompute c w/ the information given
    c = uint256_from_str(RO(ser(KX) + ser(KC)))

    assert sx.n * G == KX + c * X
    assert sx.n * G + sr.n * H == KC + c * C
    return True
Example #18
0
def pedersen_test():
    x = uint256_from_str(os.urandom(32))
    X = x * G

    C, r = make_pedersen_commitment(x)

    prf = pedersen_prover(C, X, x, r)
    (KX, KC, sx, sr) = prf
    # print(repr((ser(C), ser(KX),ser(KC),uint256_to_str(sx.n).hex(),uint256_to_str(sr.n).hex())))

    assert pedersen_verifier(C, X, prf)
    print("Pedersen correctness test complete!")
Example #19
0
def dlog_simulator(A, rnd_bytes):
    """
    Returns:
    - (prf, transcript)
    - prf, a tuple of the form (K,s),
        where K is a Point
        and s is an element of Fp
    - transcript is an array consisting of elements of the form
        [...(q,h)...]
      where each q is a query (a string)
      and each h is the response (a 32-byte string)
    """
    # TODO: Fill in your code here (10 points)
    transcript = []
    h = rnd_bytes(32)
    c = uint256_from_str(h)
    s = uint256_from_str(rnd_bytes(32)) % order
    K = s * G - c * A
    q = ser(K)
    transcript.append((q, h))
    return ((K, Fp(s)), transcript)
Example #20
0
def OR_prover(A, B, x, rnd_bytes=os.urandom, RO=sha2):
    assert x * G == A or x * G == B

    # TODO: Fill your code in here (20 points)
    ka = uint256_from_str(rnd_bytes(32)) % order
    kb = uint256_from_str(rnd_bytes(32)) % order

    KA = ka * G
    KB = kb * G
    c = uint256_from_str(RO(ser(KA) + ser(KB)))

    if x * G != B:
        ca = c
        cb = x * order
    else:
        ca = x * order
        cb = c

    sa = Fp(ka + x * ca)
    sb = Fp(kb + x * cb)

    return (KA, KB, sa, sb, ca, cb)
Example #21
0
def arith_verifier(A, B, C, prf, rnd_bytes=os.urandom, RO=sha2):
    (KA, KB, KC, sa, sb) = prf
    assert type(KA) == type(KB) == type(KC) == Point
    assert type(sa) == type(sb) == Fp

    # TODO: fill in your code here (10 points)
    c = uint256_from_str(RO(ser(KA) + ser(KB) + ser(KC)))

    assert sa.n * G == KA + c * A
    assert sb.n * G == KB + c * B
    assert sb.n * A == KC + c * (C + 3 * A)

    return True
Example #22
0
def dlog_test_extractor():
    import os
    # Make a test case based on running the real prover
    a = uint256_from_str(os.urandom(32))
    A = a * G

    def Adv(A, rnd_bytes, RO):
        assert A == a * G
        return dlog_prover(A, a, rnd_bytes, RO)

    a_ = dlog_extractor(A, Adv)
    assert a == a_
    print('Extractor test complete!')
Example #23
0
def pederson_vector_test():
    x_arr, r_arr, C_arr = [], [], []
    for _ in range(10):
        x_elem = uint256_from_str(os.urandom(32))
        C_elem, r_elem = make_pedersen_commitment(x_elem)
        x_arr.append(x_elem)
        C_arr.append(C_elem)
        r_arr.append(r_elem)

    prf = pedersen_vector_prover(C_arr, x_arr, r_arr)

    assert pedersen_vector_verifier(C_arr, prf)
    print("Pedersen vector correctness test complete!")
Example #24
0
def OR_verifier(A, B, prf, RO=sha2):
    (KA, KB, sa, sb, ca, cb) = prf
    assert type(KA) is type(KB) is Point
    assert type(sa) is type(sb) is Fp

    # Check the challenges are correctly constrained
    c = uint256_from_str(RO(ser(KA) + ser(KB)))
    assert (ca + cb) % p == c

    # Check each proof the same way
    assert sa.n * G == KA + ca * A
    assert sb.n * G == KB + cb * B

    return True
def sender_round1(rnd_bytes=os.urandom):
    """
    Inputs:
       none
    Returns:
       (a, A)   

       A is sent to receiver, 
       a is stored and passed to sender_round3
    """
    # TODO: Your code goes here
    a = Fp(uint256_from_str(rnd_bytes(32)) % order)
    A = a.n * G

    return a, A
Example #26
0
def pedersen_vector_verifier(C_arr, prf, rnd_bytes=os.urandom, RO=sha2):
    (C0, sx, sr) = prf

    assert type(C0) == Point
    assert type(sx) == type(sr) == Fp

    c = Fp(uint256_from_str(RO(ser(C0))))

    e = c
    C_final = C0
    for C_elem in C_arr:
        C_final = C_final + e.n * C_elem
        e = Fp(e * c)

    assert C_final == sx.n * G + sr.n * H

    return True
def receiver_round2(c, A, rnd_bytes=os.urandom, RO=sha2):
    """
    Inputs:
       c  a bit 0 or 1
       A  the round1 message from the sender
    Returns:
       (kR, B)
       B is sent to the sender,
       kR is the decryption key, stored and passed to sender_round4
    """
    assert c in (0, 1)
    assert type(A) is Point

    # TODO: Your code goes here
    b = Fp(uint256_from_str(rnd_bytes(32)) % order)
    B = b.n * G if c == 0 else A + b.n * G
    kR = RO(ser(b.n * A))

    return kR, B
Example #28
0
def dlog_test_simulator():
    rnd_bytes = os.urandom
    # Test with a randomly generated point on curve
    A = random_point(rnd_bytes=rnd_bytes)

    (prf, transcript) = dlog_simulator(A, rnd_bytes)

    # Unpack the proof
    K, s = prf
    assert type(K) is Point
    assert type(s) is Fp

    # Unpack oracle transcript (there should be just one query)
    assert len(transcript) == 1
    (q, h) = transcript[0]

    assert q == ser(K)
    c = uint256_from_str(h)

    # Check the verification condition
    assert s.n * G == K + c * A

    print("DLOG simulator test complete!")
Example #29
0
def dlog_test():
    a = uint256_from_str(os.urandom(32))
    A = a * G
    prf = dlog_prover(A, a)
    assert dlog_verifier(A, prf)
    print('Dlog correctness test complete!')
Example #30
0
def make_pedersen_commitment(x, rnd_bytes=os.urandom):
    r = uint256_from_str(rnd_bytes(32))
    C = x * G + r * H
    return C, r