func EncryptPoint(g abstract.Group, msgPt abstract.Point, pk abstract.Point) (abstract.Point, abstract.Point) { k := g.Secret().Pick(random.Stream) c1 := g.Point().Mul(nil, k) c2 := g.Point().Mul(pk, k) c2 = c2.Add(c2, msgPt) return c1, c2 }
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 }
// 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 }
func EncryptKey(g abstract.Group, msgPt abstract.Point, pks []abstract.Point) (abstract.Point, abstract.Point) { k := g.Secret().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 }
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.Secret().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 }
// 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 Secret\n", // g.String(), g.PointLen(), g.SecretLen()) points := make([]abstract.Point, 0) ptmp := g.Point() stmp := g.Secret() pzero := g.Point().Null() szero := g.Secret().Zero() sone := g.Secret().One() // Do a simple Diffie-Hellman test s1 := g.Secret().Pick(rand) s2 := g.Secret().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.Secret().Inv(s2)) if !ptmp.Equal(p1) { panic("Secret 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.Secret().Neg(s2) st2.Add(s1, st2) if !stmp.Equal(st2) { panic("Secret.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("Secret division doesn't work") } st2.Div(stmp, s2) if !st2.Equal(s1) { panic("Secret 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.Secret().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) } return points }
/* 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.Secret().Pick(random.Stream) var point = group.Point().Mul(group.Point().Base(), secret) var altSecret = altGroup.Secret().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 * needs that do not warrant their own set-up function. */ // Tests that checks whether a method panics can use this funcition func deferTest(t *testing.T, message string) {