// Initialize Residue group parameters for a quadratic residue group, // by picking primes P and Q such that P=2Q+1 // and the smallest valid generator G for this group. func (g *ResidueGroup) QuadraticResidueGroup(bitlen uint, rand cipher.Stream) { g.R = two // pick primes p,q such that p = 2q+1 fmt.Printf("Generating %d-bit QR group", bitlen) for i := 0; ; i++ { if i > 1000 { print(".") i = 0 } // First pick a prime Q b := random.Bits(bitlen-1, true, rand) b[len(b)-1] |= 1 // must be odd g.Q = new(big.Int).SetBytes(b) //println("q?",hex.EncodeToString(g.Q.Bytes())) if !isPrime(g.Q) { continue } // Does the corresponding P come out prime too? g.P = new(big.Int) g.P.Mul(g.Q, two) g.P.Add(g.P, one) //println("p?",hex.EncodeToString(g.P.Bytes())) if uint(g.P.BitLen()) == bitlen && isPrime(g.P) { break } } println() println("p", g.P.String()) println("q", g.Q.String()) // pick standard generator G h := new(big.Int).Set(two) g.G = new(big.Int) for { g.G.Exp(h, two, g.P) if g.G.Cmp(one) != 0 { break } h.Add(h, one) } println("g", g.G.String()) }
// Pick a curve point containing a variable amount of embedded data. // Remaining bits comprising the point are chosen randomly. func (p *curvePoint) Pick(data []byte, rand cipher.Stream) (abstract.Point, []byte) { l := p.c.coordLen() dl := p.PickLen() if dl > len(data) { dl = len(data) } for { b := random.Bits(uint(p.c.p.P.BitLen()), false, rand) if data != nil { b[l-1] = byte(dl) // Encode length in low 8 bits copy(b[l-dl-1:l-1], data) // Copy in data to embed } if p.genPoint(new(big.Int).SetBytes(b), rand) { return p, data[dl:] } } }
// Pick a point containing a variable amount of embedded data. // Remaining bits comprising the point are chosen randomly. // This will only work efficiently for quadratic residue groups! func (p *residuePoint) Pick(data []byte, rand cipher.Stream) (abstract.Point, []byte) { l := p.g.PointLen() dl := p.PickLen() if dl > len(data) { dl = len(data) } for { b := random.Bits(uint(p.g.P.BitLen()), false, rand) if data != nil { b[l-1] = byte(dl) // Encode length in low 16 bits b[l-2] = byte(dl >> 8) copy(b[l-dl-2:l-2], data) // Copy in embedded data } p.Int.SetBytes(b) if p.Valid() { return p, data[dl:] } } }