跳转至

collusion

exp.py

package main

import (
    "crypto/rand"
    "encoding/json"
    "fmt"
    "math/big"
    "io/ioutil"
    "log"
)

// Not sure why this isn't in common.go; it's the trivial inverse of Encrypt
func Decrypt(d *Decrypter, payload *Payload) (string, error) {
    shared := d.RecoverKey(payload.V)
    block, err := aes.NewCipher(shared)
    if err != nil {
        return "", err
    }
    ciph, err := cipher.NewGCM(block)
    if err != nil {
        return "", err
    }
    message, err := ciph.Open(nil, payload.Nonce, payload.Body, nil)
    if err != nil {
        return "", err
    }
    return string(message), nil
}

const TEST = 0

func main() {
    var g *Group
    var dB *Decrypter
    var dC *Decrypter
    var payload *Payload

    if TEST != 0 {
        // Test group
        var err error
        g, err = NewGroup(rand.Reader, 1024)
        if err != nil {
            log.Fatal(err)
        }
        dB, err = g.Decrypter("Bob")
        if err != nil {
            log.Fatal(err)
        }
        dC, err = g.Decrypter("Carol")
        if err != nil {
            log.Fatal(err)
        }

        e := g.Encrypter()
        payload, err = Encrypt(e, "Alice", "flag{testflag}")
        if err != nil {
            log.Fatal(err)
        }
    } else {
        // Load the challenge
        dB = new(Decrypter)
        if err := loadFromFile("bobs-key.json", &dB); err != nil {
            log.Fatal(err)
        }
        dC = new(Decrypter)
        if err := loadFromFile("carols-key.json", &dC); err != nil {
            log.Fatal(err)
        }

        if dB.N.Cmp(dC.N) != 0 {
            log.Fatal("N doesn't match!")
        }

        payload = new(Payload)
        if err := loadFromFile("message.json", &payload); err != nil {
            log.Fatal(err)
        }
    }

    N := new(big.Int).Set(dB.N)

    aId, err := DecrypterId("Alice", N)
    if err != nil {
        log.Fatal(err)
    }

    bId, err := DecrypterId("Bob", N)
    if err != nil {
        log.Fatal(err)
    }

    cId, err := DecrypterId("Carol", N)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Alice's ID", aId)
    fmt.Println("Bob's ID", bId)
    fmt.Println("Carol's ID", cId)

    myPhi := new(big.Int)
    myPhi.Sub(bId, cId).Mul(myPhi, dB.D).Mul(myPhi, dC.D)
    myPhi.Add(myPhi, dB.D).Sub(myPhi, dC.D)
    myPhi.Abs(myPhi)

    fmt.Println("myPhi", myPhi)

    if TEST != 0 {
        fmt.Println("phi", phi(g.P, g.Q))
        fmt.Println("residue", new(big.Int).Mod(myPhi, phi(g.P, g.Q)))
    }

    xB := new(big.Int).ModInverse(dB.D, myPhi)
    if xB == nil {
        log.Fatal("Not relatively prime!")
    }

    x := new(big.Int).Sub(xB, bId)
    x.Mod(x, myPhi)

    xA := new(big.Int).Add(x, aId)
    xA.Mod(xA, myPhi)

    dA := &Decrypter {
        N: N,
        D: new(big.Int).ModInverse(xA, myPhi),
    }

    if TEST != 0 {
        fmt.Println("my dA", new(big.Int).Mod(dA.D, phi(g.P, g.Q)))
        realDA, err := g.Decrypter("Alice")
        if err != nil {
            panic(err)
        }
        fmt.Println("real dA", realDA.D)
    }

    message, err := Decrypt(dA, payload)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("message", message)
}

func loadFromFile(name string, x interface{}) error {
    raw, err := ioutil.ReadFile(name)
    if err != nil {
        return err
    }
    return json.Unmarshal(raw, x)
}


评论