Beispiel #1
0
// InitNull does the same thing as Init PLUS initialize every points / coef to the Null
// Identity Element so we can use it like a "temp" / "aggregate" variable to add with others poly
func (pub *PubPoly) InitNull(g abstract.Group, k int, b abstract.Point) *PubPoly {
	pub.Init(g, k, b)
	for i, _ := range pub.p {
		pub.p[i] = g.Point().Null()
	}
	return pub
}
Beispiel #2
0
func EncryptPoint(g abstract.Group, msgPt abstract.Point, pk abstract.Point) (abstract.Point, abstract.Point) {
	k := g.Scalar().Pick(random.Stream)
	c1 := g.Point().Mul(nil, k)
	c2 := g.Point().Mul(pk, k)
	c2 = c2.Add(c2, msgPt)
	return c1, c2
}
Beispiel #3
0
func testHiding(g abstract.Group, k int) {
	rand := random.Stream

	// Test conversion from random strings to points and back
	p := g.Point()
	p2 := g.Point()
	l := p.(abstract.Hiding).HideLen()
	buf := make([]byte, l)
	for i := 0; i < k; i++ {
		rand.XORKeyStream(buf, buf)
		//println("R "+hex.EncodeToString(buf))
		p.(abstract.Hiding).HideDecode(buf)
		//println("P "+p.String())
		b2 := p.(abstract.Hiding).HideEncode(rand)
		if b2 == nil {
			panic("HideEncode failed")
		}
		//println("R'"+hex.EncodeToString(b2))
		p2.(abstract.Hiding).HideDecode(b2)
		//println("P'"+p2.String())
		if !p.Equal(p2) {
			panic("HideDecode produced wrong point")
		}
		//println("")
	}
}
Beispiel #4
0
func NewGroupBench(g abstract.Group) *GroupBench {
	var gb GroupBench
	gb.g = g
	gb.x = g.Secret().Pick(random.Stream)
	gb.y = g.Secret().Pick(random.Stream)
	gb.xe, _ = gb.x.MarshalBinary()
	gb.X, _ = g.Point().Pick(nil, random.Stream)
	gb.Y, _ = g.Point().Pick(nil, random.Stream)
	gb.Xe, _ = gb.X.MarshalBinary()
	return &gb
}
Beispiel #5
0
// Create a fresh sharing polynomial in the Secret space of a given group.
// Shares the provided Secret s, or picks a random one if s == nil.
func (p *PriPoly) Pick(g abstract.Group, k int, s0 abstract.Secret,
	rand cipher.Stream) *PriPoly {
	p.g = g
	s := make([]abstract.Secret, k)
	if s0 == nil { // Choose secret to share if none provided
		s0 = g.Secret().Pick(rand)
	}
	s[0] = s0
	for i := 1; i < k; i++ {
		s[i] = g.Secret().Pick(rand)
	}
	p.s = s
	return p
}
Beispiel #6
0
func testScalarClone(g abstract.Group, rand cipher.Stream) {
	N := 1000
	one := g.Scalar().One()
	for i := 0; i < N; i++ {
		s1 := g.Scalar().Pick(rand)
		s2 := s1.Clone()
		if !s1.Equal(s2) {
			panic("Clone didn't create a scalar s2 with same value as s1's.")
		}
		if !s1.Equal(one) {
			s1.Mul(s1, s1)
			if s1.Equal(s2) {
				panic("Modifying s1 shouldn't modify s2")
			}
		}
	}
}
Beispiel #7
0
func testPointClone(g abstract.Group, rand cipher.Stream) {
	N := 1000
	null := g.Point().Null()
	for i := 0; i < N; i++ {
		P1, _ := g.Point().Pick(nil, rand)
		P2 := P1.Clone()
		if !P1.Equal(P2) {
			panic("Clone didn't create a point with same " +
				"coordinates as the original point.")
		}
		if !P1.Equal(null) {
			P1.Add(P1, P1)
			if P1.Equal(P2) {
				panic("Modifying P1 shouldn't modify P2")
			}
		}
	}
}
Beispiel #8
0
func testEmbed(g abstract.Group, rand cipher.Stream, points *[]abstract.Point,
	s string) {
	//println("embedding: ",s)
	b := []byte(s)

	p, rem := g.Point().Pick(b, rand)
	//println("embedded, remainder",len(rem),"/",len(b),":",string(rem))
	x, err := p.Data()
	if err != nil {
		panic("Point extraction failed: " + err.Error())
	}
	//println("extracted data: ",string(x))

	if !bytes.Equal(append(x, rem...), b) {
		panic("Point embedding corrupted the data")
	}

	*points = append(*points, p)
}
Beispiel #9
0
// Simple helper to compute G^{ab-cd} for Theta vector computation.
func thenc(grp abstract.Group, G abstract.Point,
	a, b, c, d abstract.Scalar) abstract.Point {

	var ab, cd abstract.Scalar
	if a != nil {
		ab = grp.Scalar().Mul(a, b)
	} else {
		ab = grp.Scalar().Zero()
	}
	if c != nil {
		if d != nil {
			cd = grp.Scalar().Mul(c, d)
		} else {
			cd = c
		}
	} else {
		cd = grp.Scalar().Zero()
	}
	return grp.Point().Mul(G, ab.Sub(ab, cd))
}
Beispiel #10
0
func Shuffle(pi []int, group abstract.Group, g, h abstract.Point, X, Y []abstract.Point,
	rand cipher.Stream) (XX, YY []abstract.Point, P proof.Prover) {

	k := len(X)
	if k != len(Y) {
		panic("X,Y vectors have inconsistent length")
	}

	ps := shuffle.PairShuffle{}
	ps.Init(group, k)

	// Pick a fresh ElGamal blinding factor for each pair
	beta := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		beta[i] = group.Scalar().Pick(rand)
	}

	// Create the output pair vectors
	Xbar := make([]abstract.Point, k)
	Ybar := make([]abstract.Point, k)
	for i := 0; i < k; i++ {
		Xbar[i] = group.Point().Mul(g, beta[pi[i]])
		Xbar[i].Add(Xbar[i], X[pi[i]])
		Ybar[i] = group.Point().Mul(h, beta[pi[i]])
		Ybar[i].Add(Ybar[i], Y[pi[i]])
	}

	prover := func(ctx proof.ProverContext) error {
		return ps.Prove(pi, g, h, beta, X, Y, rand, ctx)
	}
	return Xbar, Ybar, prover
}
Beispiel #11
0
func EncryptKey(g abstract.Group, msgPt abstract.Point, pks []abstract.Point) (abstract.Point, abstract.Point) {
	k := g.Scalar().Pick(random.Stream)
	c1 := g.Point().Mul(nil, k)
	var c2 abstract.Point = nil
	for _, pk := range pks {
		if c2 == nil {
			c2 = g.Point().Mul(pk, k)
		} else {
			c2 = c2.Add(c2, g.Point().Mul(pk, k))
		}
	}
	c2 = c2.Add(c2, msgPt)
	return c1, c2
}
Beispiel #12
0
func Encrypt(g abstract.Group, msg []byte, pks []abstract.Point) ([]abstract.Point, []abstract.Point) {
	c1s := []abstract.Point{}
	c2s := []abstract.Point{}
	var msgPt abstract.Point
	remainder := msg
	for len(remainder) != 0 {
		msgPt, remainder = g.Point().Pick(remainder, random.Stream)
		k := g.Scalar().Pick(random.Stream)
		c1 := g.Point().Mul(nil, k)
		var c2 abstract.Point = nil
		for _, pk := range pks {
			if c2 == nil {
				c2 = g.Point().Mul(pk, k)
			} else {
				c2 = c2.Add(c2, g.Point().Mul(pk, k))
			}
		}
		c2 = c2.Add(c2, msgPt)
		c1s = append(c1s, c1)
		c2s = append(c2s, c2)
	}
	return c1s, c2s
}
Beispiel #13
0
func testPointSet(g abstract.Group, rand cipher.Stream) {
	N := 1000
	null := g.Point().Null()
	for i := 0; i < N; i++ {
		P1, _ := g.Point().Pick(nil, rand)
		P2 := g.Point()
		P2.Set(P1)
		if !P1.Equal(P2) {
			panic("Set() set to a different point.")
		}
		if !P1.Equal(null) {
			P1.Add(P1, P1)
			if P1.Equal(P2) {
				panic("Modifying P1 shouldn't modify P2")
			}
		}
	}
}
Beispiel #14
0
func Decrypt(g abstract.Group, c1 abstract.Point, c2 abstract.Point, sk abstract.Scalar) abstract.Point {
	return g.Point().Sub(c2, g.Point().Mul(c1, sk))
}
Beispiel #15
0
	"github.com/dedis/crypto/abstract"
	"github.com/dedis/crypto/edwards"
	"github.com/dedis/crypto/random"
)

/* This file is a testing suite for sharing.go. It provides multiple test cases
 * for ensuring that encryption schemes built upon this package such as Shamir
 * secret sharing are safe and secure.
 *
 * The tests can also serve as references for how to work with this library.
 */

/* Global Variables */

var group abstract.Group = new(edwards.ExtendedCurve).Init(
	edwards.Param25519(), false)
var altGroup abstract.Group = new(edwards.ProjectiveCurve).Init(
	edwards.ParamE382(), false)
var k int = 10
var n int = 20
var secret = group.Scalar().Pick(random.Stream)
var point = group.Point().Mul(group.Point().Base(), secret)
var altSecret = altGroup.Scalar().Pick(random.Stream)
var altPoint = altGroup.Point().Mul(altGroup.Point().Base(), altSecret)

/* Setup Functions
 *
 * These functions provide greater modularity by consolidating commonly used
 * setup tasks.
 *
 * Not every function uses these methods, since they may have unique set-up
Beispiel #16
0
// Apply a generic set of validation tests to a cryptographic Group,
// using a given source of [pseudo-]randomness.
//
// Returns a log of the pseudorandom Points produced in the test,
// for comparison across alternative implementations
// that are supposed to be equivalent.
//
func testGroup(g abstract.Group, rand cipher.Stream) []abstract.Point {
	//	fmt.Printf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n",
	//			g.String(), g.PointLen(), g.ScalarLen())

	points := make([]abstract.Point, 0)
	ptmp := g.Point()
	stmp := g.Scalar()
	pzero := g.Point().Null()
	szero := g.Scalar().Zero()
	sone := g.Scalar().One()

	// Do a simple Diffie-Hellman test
	s1 := g.Scalar().Pick(rand)
	s2 := g.Scalar().Pick(rand)
	if s1.Equal(s2) {
		panic("uh-oh, not getting unique secrets!")
	}

	gen := g.Point().Base()
	points = append(points, gen)

	// Verify additive and multiplicative identities of the generator.
	ptmp.Mul(nil, stmp.SetInt64(-1)).Add(ptmp, gen)
	if !ptmp.Equal(pzero) {
		panic("oops, generator additive identity doesn't work")
	}
	if g.PrimeOrder() { // secret.Inv works only in prime-order groups
		ptmp.Mul(nil, stmp.SetInt64(2)).Mul(ptmp, stmp.Inv(stmp))
		if !ptmp.Equal(gen) {
			panic("oops, generator multiplicative identity doesn't work")
		}
	}

	p1 := g.Point().Mul(gen, s1)
	p2 := g.Point().Mul(gen, s2)
	if p1.Equal(p2) {
		panic("uh-oh, encryption isn't producing unique points!")
	}
	points = append(points, p1)

	dh1 := g.Point().Mul(p1, s2)
	dh2 := g.Point().Mul(p2, s1)
	if !dh1.Equal(dh2) {
		panic("Diffie-Hellman didn't work")
	}
	points = append(points, dh1)
	//println("shared secret = ",dh1.String())

	// Test secret inverse to get from dh1 back to p1
	if g.PrimeOrder() {
		ptmp.Mul(dh1, g.Scalar().Inv(s2))
		if !ptmp.Equal(p1) {
			panic("Scalar inverse didn't work")
		}
	}

	// Zero and One identity secrets
	//println("dh1^0 = ",ptmp.Mul(dh1, szero).String())
	if !ptmp.Mul(dh1, szero).Equal(pzero) {
		panic("Encryption with secret=0 didn't work")
	}
	if !ptmp.Mul(dh1, sone).Equal(dh1) {
		panic("Encryption with secret=1 didn't work")
	}

	// Additive homomorphic identities
	ptmp.Add(p1, p2)
	stmp.Add(s1, s2)
	pt2 := g.Point().Mul(gen, stmp)
	if !pt2.Equal(ptmp) {
		panic("Additive homomorphism doesn't work")
	}
	ptmp.Sub(p1, p2)
	stmp.Sub(s1, s2)
	pt2.Mul(gen, stmp)
	if !pt2.Equal(ptmp) {
		panic("Additive homomorphism doesn't work")
	}
	st2 := g.Scalar().Neg(s2)
	st2.Add(s1, st2)
	if !stmp.Equal(st2) {
		panic("Scalar.Neg doesn't work")
	}
	pt2.Neg(p2).Add(pt2, p1)
	if !pt2.Equal(ptmp) {
		panic("Point.Neg doesn't work")
	}

	// Multiplicative homomorphic identities
	stmp.Mul(s1, s2)
	if !ptmp.Mul(gen, stmp).Equal(dh1) {
		panic("Multiplicative homomorphism doesn't work")
	}
	if g.PrimeOrder() {
		st2.Inv(s2)
		st2.Mul(st2, stmp)
		if !st2.Equal(s1) {
			panic("Scalar division doesn't work")
		}
		st2.Div(stmp, s2)
		if !st2.Equal(s1) {
			panic("Scalar division doesn't work")
		}
	}

	// Test randomly picked points
	last := gen
	for i := 0; i < 5; i++ {
		rgen, _ := g.Point().Pick(nil, rand)
		if rgen.Equal(last) {
			panic("Pick() not producing unique points")
		}
		last = rgen

		ptmp.Mul(rgen, stmp.SetInt64(-1)).Add(ptmp, rgen)
		if !ptmp.Equal(pzero) {
			panic("random generator fails additive identity")
		}
		if g.PrimeOrder() {
			ptmp.Mul(rgen, stmp.SetInt64(2)).Mul(ptmp, stmp.Inv(stmp))
			if !ptmp.Equal(rgen) {
				panic("random generator fails multiplicative identity")
			}
		}
		points = append(points, rgen)
	}

	// Test embedding data
	testEmbed(g, rand, &points, "Hi!")
	testEmbed(g, rand, &points, "The quick brown fox jumps over the lazy dog")

	// Test verifiable secret sharing
	// XXX re-enable when we move this into 'test' sub-package
	//testSharing(g)

	// Test encoding and decoding
	buf := new(bytes.Buffer)
	for i := 0; i < 5; i++ {
		buf.Reset()
		s := g.Scalar().Pick(rand)
		if _, err := s.MarshalTo(buf); err != nil {
			panic("encoding of secret fails: " + err.Error())
		}
		if _, err := stmp.UnmarshalFrom(buf); err != nil {
			panic("decoding of secret fails: " + err.Error())
		}
		if !stmp.Equal(s) {
			panic("decoding produces different secret than encoded")
		}

		buf.Reset()
		p, _ := g.Point().Pick(nil, rand)
		if _, err := p.MarshalTo(buf); err != nil {
			panic("encoding of point fails: " + err.Error())
		}
		if _, err := ptmp.UnmarshalFrom(buf); err != nil {
			panic("decoding of point fails: " + err.Error())
		}
		if !ptmp.Equal(p) {
			panic("decoding produces different point than encoded")
		}
	}

	// Test that we can marshal/ unmarshal null point
	pzero = g.Point().Null()
	b, _ := pzero.MarshalBinary()
	repzero := g.Point()
	err := repzero.UnmarshalBinary(b)
	if err != nil {
		panic(err)
	}

	testPointSet(g, rand)
	testPointClone(g, rand)
	testScalarSet(g, rand)
	testScalarClone(g, rand)

	return points
}
Beispiel #17
0
func testSharing(g abstract.Group) {

	k := 4
	n := 10
	p1 := new(PriPoly).Pick(g, k, nil, random.Stream)
	p2 := new(PriPoly).Pick(g, k, nil, random.Stream)
	p3 := new(PriPoly).Add(p1, p2)
	if p1.Equal(p2) || p1.Equal(p3) || !p1.Equal(p1) || !p2.Equal(p2) {
		panic("PriPoly equality doesn't work")
	}

	pub1 := new(PubPoly).Commit(p1, nil)
	pub2 := new(PubPoly).Commit(p2, nil)
	pub3 := new(PubPoly).Commit(p3, nil)
	if pub1.Equal(pub2) || pub1.Equal(pub3) {
		panic("PubPoly equality false positive")
	}
	if !pub1.Equal(pub1) || !pub2.Equal(pub2) {
		panic("PubPoly equality false negative")
	}
	pub3c := new(PubPoly).Add(pub1, pub2)
	if !pub3.Equal(pub3c) {
		panic("PubPoly homomorphic addition doesn't work")
	}

	ps1 := new(PriShares).Split(p1, n)
	if !ps1.Secret().Equal(p1.Secret()) {
		panic("Secret recovery doesn't work!")
	}

	// Share-checking
	for i := 0; i < n; i++ {
		if !pub1.Check(i, ps1.Share(i)) {
			panic("Share checking doesn't work")
		}
		if pub2.Check(i, ps1.Share(i)) {
			panic("Share checking false positive!?")
		}
	}

	// Produce share commitments from the public polynomial commitment.
	pubs1 := new(PubShares).Split(pub1, n)
	for i := 0; i < n; i++ {
		P := g.Point().Mul(nil, ps1.Share(i))
		if !P.Equal(pubs1.Share(i)) {
			panic("Homomorphic share splitting didn't work")
		}
	}

	// Cut out even-numbered shares for fun
	for i := 0; i < n; i += 2 {
		ps1.SetShare(i, nil)
		pubs1.SetShare(i, nil)
	}
	if !ps1.Secret().Equal(p1.Secret()) {
		panic("Secret recovery from partial set doesn't work!")
	}

	// Homomorphic share reconstruction
	P := g.Point().Mul(nil, p1.Secret())
	if !P.Equal(pub1.SecretCommit()) {
		panic("Public polynomial committed wrong secret")
	}
	if !P.Equal(pubs1.SecretCommit()) {
		panic("Homomorphic secret reconstruction didn't work")
	}

	// Cut to the minimum number of shares
	ps1.SetShare(1, nil)
	if !ps1.Secret().Equal(p1.Secret()) {
		panic("Secret recovery from partial set doesn't work!")
	}
	if !P.Equal(pubs1.SecretCommit()) {
		panic("Homomorphic secret reconstruction didn't work")
	}
}